MediaRouteControllerDialog.java revision 328f1006c17ddeb3eb563580bcd6638e1cfb4320
111417b1cfde8f1749905f2d735623af9214148afJeff Brown/*
211417b1cfde8f1749905f2d735623af9214148afJeff Brown * Copyright (C) 2013 The Android Open Source Project
311417b1cfde8f1749905f2d735623af9214148afJeff Brown *
411417b1cfde8f1749905f2d735623af9214148afJeff Brown * Licensed under the Apache License, Version 2.0 (the "License");
511417b1cfde8f1749905f2d735623af9214148afJeff Brown * you may not use this file except in compliance with the License.
611417b1cfde8f1749905f2d735623af9214148afJeff Brown * You may obtain a copy of the License at
711417b1cfde8f1749905f2d735623af9214148afJeff Brown *
811417b1cfde8f1749905f2d735623af9214148afJeff Brown *      http://www.apache.org/licenses/LICENSE-2.0
911417b1cfde8f1749905f2d735623af9214148afJeff Brown *
1011417b1cfde8f1749905f2d735623af9214148afJeff Brown * Unless required by applicable law or agreed to in writing, software
1111417b1cfde8f1749905f2d735623af9214148afJeff Brown * distributed under the License is distributed on an "AS IS" BASIS,
1211417b1cfde8f1749905f2d735623af9214148afJeff Brown * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1311417b1cfde8f1749905f2d735623af9214148afJeff Brown * See the License for the specific language governing permissions and
1411417b1cfde8f1749905f2d735623af9214148afJeff Brown * limitations under the License.
1511417b1cfde8f1749905f2d735623af9214148afJeff Brown */
1611417b1cfde8f1749905f2d735623af9214148afJeff Brown
1711417b1cfde8f1749905f2d735623af9214148afJeff Brownpackage android.support.v7.app;
1811417b1cfde8f1749905f2d735623af9214148afJeff Brown
19bfb90b6717bb46535d747aa50045a206965542d0Jae Seoimport static android.widget.SeekBar.OnSeekBarChangeListener;
20bfb90b6717bb46535d747aa50045a206965542d0Jae Seo
21005482649154d0970693b3967241eb4d2cb22003Jaewan Kimimport android.content.ContentResolver;
2211417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.content.Context;
23c5738b858579021cc89fffd8a891b4c5ea8c0f83Jaewan Kimimport android.content.res.Resources;
24005482649154d0970693b3967241eb4d2cb22003Jaewan Kimimport android.graphics.Bitmap;
25005482649154d0970693b3967241eb4d2cb22003Jaewan Kimimport android.graphics.BitmapFactory;
262c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kimimport android.graphics.Rect;
2713d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kimimport android.graphics.drawable.BitmapDrawable;
28005482649154d0970693b3967241eb4d2cb22003Jaewan Kimimport android.net.Uri;
29005482649154d0970693b3967241eb4d2cb22003Jaewan Kimimport android.os.AsyncTask;
3011417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.os.Bundle;
3194be6100218126ce6a08bf1f56209578500b361fRoboErikimport android.os.RemoteException;
3294be6100218126ce6a08bf1f56209578500b361fRoboErikimport android.support.v4.media.MediaDescriptionCompat;
3394be6100218126ce6a08bf1f56209578500b361fRoboErikimport android.support.v4.media.MediaMetadataCompat;
3494be6100218126ce6a08bf1f56209578500b361fRoboErikimport android.support.v4.media.session.MediaControllerCompat;
3594be6100218126ce6a08bf1f56209578500b361fRoboErikimport android.support.v4.media.session.MediaSessionCompat;
3694be6100218126ce6a08bf1f56209578500b361fRoboErikimport android.support.v4.media.session.PlaybackStateCompat;
37ee7ae661b02471fe598566b1e90adbacda240b0bJae Seoimport android.support.v4.view.accessibility.AccessibilityEventCompat;
38005482649154d0970693b3967241eb4d2cb22003Jaewan Kimimport android.support.v7.graphics.Palette;
3911417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.support.v7.media.MediaRouteSelector;
4011417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.support.v7.media.MediaRouter;
4111417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.support.v7.mediarouter.R;
4294be6100218126ce6a08bf1f56209578500b361fRoboErikimport android.text.TextUtils;
4394be6100218126ce6a08bf1f56209578500b361fRoboErikimport android.util.Log;
4406991009e52024cbb3dde550988e06149e77a269Jae Seoimport android.util.TypedValue;
4511417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.view.KeyEvent;
466051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seoimport android.view.LayoutInflater;
4711417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.view.View;
4840dd800ece983a94ea6a26a27481da50f489e7c8Jaewan Kimimport android.view.View.MeasureSpec;
496051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seoimport android.view.ViewGroup;
5086dcb627078ea297c4337ed634fc3fe874e23897Jae Seoimport android.view.ViewTreeObserver;
51ee7ae661b02471fe598566b1e90adbacda240b0bJae Seoimport android.view.accessibility.AccessibilityEvent;
52ee7ae661b02471fe598566b1e90adbacda240b0bJae Seoimport android.view.accessibility.AccessibilityManager;
536051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seoimport android.widget.ArrayAdapter;
5411417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.widget.Button;
5511417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.widget.FrameLayout;
5694be6100218126ce6a08bf1f56209578500b361fRoboErikimport android.widget.ImageButton;
5794be6100218126ce6a08bf1f56209578500b361fRoboErikimport android.widget.ImageView;
58f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shahimport android.widget.LinearLayout;
596051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seoimport android.widget.ListView;
607ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Limimport android.widget.RelativeLayout;
61f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shahimport android.widget.SeekBar;
6294be6100218126ce6a08bf1f56209578500b361fRoboErikimport android.widget.TextView;
6311417b1cfde8f1749905f2d735623af9214148afJeff Brown
64005482649154d0970693b3967241eb4d2cb22003Jaewan Kimimport java.io.BufferedInputStream;
65005482649154d0970693b3967241eb4d2cb22003Jaewan Kimimport java.io.IOException;
666051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seoimport java.util.List;
67005482649154d0970693b3967241eb4d2cb22003Jaewan Kim
6811417b1cfde8f1749905f2d735623af9214148afJeff Brown/**
6911417b1cfde8f1749905f2d735623af9214148afJeff Brown * This class implements the route controller dialog for {@link MediaRouter}.
7011417b1cfde8f1749905f2d735623af9214148afJeff Brown * <p>
7111417b1cfde8f1749905f2d735623af9214148afJeff Brown * This dialog allows the user to control or disconnect from the currently selected route.
7211417b1cfde8f1749905f2d735623af9214148afJeff Brown * </p>
7311417b1cfde8f1749905f2d735623af9214148afJeff Brown *
7411417b1cfde8f1749905f2d735623af9214148afJeff Brown * @see MediaRouteButton
7511417b1cfde8f1749905f2d735623af9214148afJeff Brown * @see MediaRouteActionProvider
7611417b1cfde8f1749905f2d735623af9214148afJeff Brown */
7789530d511efd566d53bedd9178454dd01d227c61Jae Seopublic class MediaRouteControllerDialog extends AlertDialog {
7811417b1cfde8f1749905f2d735623af9214148afJeff Brown    private static final String TAG = "MediaRouteControllerDialog";
7911417b1cfde8f1749905f2d735623af9214148afJeff Brown
80f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah    // Time to wait before updating the volume when the user lets go of the seek bar
81f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah    // to allow the route provider time to propagate the change and publish a new
82f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah    // route descriptor.
83f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah    private static final int VOLUME_UPDATE_DELAY_MILLIS = 250;
84435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim    private static final int VOLUME_SLIDER_TAG_MASTER = 0;
85435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim    private static final int VOLUME_SLIDER_TAG_BASE = 100;
86f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah
8706991009e52024cbb3dde550988e06149e77a269Jae Seo    private static final int BUTTON_NEUTRAL_RES_ID = android.R.id.button3;
8806991009e52024cbb3dde550988e06149e77a269Jae Seo    private static final int BUTTON_DISCONNECT_RES_ID = android.R.id.button2;
8906991009e52024cbb3dde550988e06149e77a269Jae Seo    private static final int BUTTON_STOP_RES_ID = android.R.id.button1;
9006991009e52024cbb3dde550988e06149e77a269Jae Seo
9111417b1cfde8f1749905f2d735623af9214148afJeff Brown    private final MediaRouter mRouter;
9211417b1cfde8f1749905f2d735623af9214148afJeff Brown    private final MediaRouterCallback mCallback;
9311417b1cfde8f1749905f2d735623af9214148afJeff Brown    private final MediaRouter.RouteInfo mRoute;
9411417b1cfde8f1749905f2d735623af9214148afJeff Brown
95eff7719415542ba819054863b0995f07742a7a8aJeff Brown    private boolean mCreated;
96e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik    private boolean mAttachedToWindow;
97e2148398ae5d03c22789aebc3d6359b5ff86c077Jae Seo
98f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seo    private int mDialogContentWidth;
9911417b1cfde8f1749905f2d735623af9214148afJeff Brown
1007ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim    private View mCustomControlView;
10111417b1cfde8f1749905f2d735623af9214148afJeff Brown
10211417b1cfde8f1749905f2d735623af9214148afJeff Brown    private Button mDisconnectButton;
10394be6100218126ce6a08bf1f56209578500b361fRoboErik    private Button mStopCastingButton;
1041ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim    private ImageButton mPlayPauseButton;
105b48ccf48b0281e69262fc643d0def898aede407bSungsoo Lim    private ImageButton mCloseButton;
106328f1006c17ddeb3eb563580bcd6638e1cfb4320Jaewan Kim    private MediaRouteExpandCollapseButton mGroupExpandCollapseButton;
10794be6100218126ce6a08bf1f56209578500b361fRoboErik
1081ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim    private FrameLayout mCustomControlLayout;
1092b274bd3e06bd33c9b2a0851256afcda94d96395Dongwon Kang    private FrameLayout mDefaultControlLayout;
11094be6100218126ce6a08bf1f56209578500b361fRoboErik    private ImageView mArtView;
1111ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim    private TextView mTitleView;
1121ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim    private TextView mSubtitleView;
1137ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim    private TextView mRouteNameTextView;
11494be6100218126ce6a08bf1f56209578500b361fRoboErik
115f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah    private boolean mVolumeControlEnabled = true;
1162c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim    // Layout for media controllers including play/pause button, volume slider,
1172c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim    // and group volume sliders.
1188e1281a26eaabd6422fd84c11010134a0a9c3338Jaewan Kim    private LinearLayout mMediaControlLayout;
1192c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim    // Layout for media controllers including play/pause button and volume slider.
1202c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim    private LinearLayout mMediaMainControlLayout;
1211ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim    private RelativeLayout mPlaybackControl;
1221ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim    private LinearLayout mVolumeControl;
1231ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim    private View mDividerView;
1241ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim
1256051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo    private ListView mVolumeGroupList;
1261ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim    private SeekBar mVolumeSlider;
127435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim    private VolumeChangeListener mVolumeChangeListener;
1281ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim    private boolean mVolumeSliderTouched;
129c5738b858579021cc89fffd8a891b4c5ea8c0f83Jaewan Kim    private int mVolumeGroupListItemIconSize;
130c5738b858579021cc89fffd8a891b4c5ea8c0f83Jaewan Kim    private int mVolumeGroupListItemHeight;
131c5738b858579021cc89fffd8a891b4c5ea8c0f83Jaewan Kim    private int mVolumeGroupListMaxHeight;
132c5738b858579021cc89fffd8a891b4c5ea8c0f83Jaewan Kim    private final int mVolumeGroupListPaddingTop;
133f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah
13494be6100218126ce6a08bf1f56209578500b361fRoboErik    private MediaControllerCompat mMediaController;
13594be6100218126ce6a08bf1f56209578500b361fRoboErik    private MediaControllerCallback mControllerCallback;
13694be6100218126ce6a08bf1f56209578500b361fRoboErik    private PlaybackStateCompat mState;
13794be6100218126ce6a08bf1f56209578500b361fRoboErik    private MediaDescriptionCompat mDescription;
13894be6100218126ce6a08bf1f56209578500b361fRoboErik
139005482649154d0970693b3967241eb4d2cb22003Jaewan Kim    private FetchArtTask mFetchArtTask;
1408bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo    private Bitmap mArtIconBitmap;
1418bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo    private Uri mArtIconUri;
1422b274bd3e06bd33c9b2a0851256afcda94d96395Dongwon Kang    private boolean mIsGroupExpanded;
14311417b1cfde8f1749905f2d735623af9214148afJeff Brown
144ee7ae661b02471fe598566b1e90adbacda240b0bJae Seo    private final AccessibilityManager mAccessibilityManager;
145ee7ae661b02471fe598566b1e90adbacda240b0bJae Seo
14611417b1cfde8f1749905f2d735623af9214148afJeff Brown    public MediaRouteControllerDialog(Context context) {
14711417b1cfde8f1749905f2d735623af9214148afJeff Brown        this(context, 0);
14811417b1cfde8f1749905f2d735623af9214148afJeff Brown    }
14911417b1cfde8f1749905f2d735623af9214148afJeff Brown
15011417b1cfde8f1749905f2d735623af9214148afJeff Brown    public MediaRouteControllerDialog(Context context, int theme) {
15194be6100218126ce6a08bf1f56209578500b361fRoboErik        super(MediaRouterThemeHelper.createThemedContext(context), theme);
15211417b1cfde8f1749905f2d735623af9214148afJeff Brown        context = getContext();
15311417b1cfde8f1749905f2d735623af9214148afJeff Brown
15494be6100218126ce6a08bf1f56209578500b361fRoboErik        mControllerCallback = new MediaControllerCallback();
15511417b1cfde8f1749905f2d735623af9214148afJeff Brown        mRouter = MediaRouter.getInstance(context);
15611417b1cfde8f1749905f2d735623af9214148afJeff Brown        mCallback = new MediaRouterCallback();
15711417b1cfde8f1749905f2d735623af9214148afJeff Brown        mRoute = mRouter.getSelectedRoute();
158e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik        setMediaSession(mRouter.getMediaSessionToken());
159c5738b858579021cc89fffd8a891b4c5ea8c0f83Jaewan Kim        mVolumeGroupListPaddingTop = context.getResources().getDimensionPixelSize(
160c5738b858579021cc89fffd8a891b4c5ea8c0f83Jaewan Kim                R.dimen.mr_controller_volume_group_list_padding_top);
161ee7ae661b02471fe598566b1e90adbacda240b0bJae Seo        mAccessibilityManager =
162ee7ae661b02471fe598566b1e90adbacda240b0bJae Seo                (AccessibilityManager) context.getSystemService(Context.ACCESSIBILITY_SERVICE);
16311417b1cfde8f1749905f2d735623af9214148afJeff Brown    }
16411417b1cfde8f1749905f2d735623af9214148afJeff Brown
16511417b1cfde8f1749905f2d735623af9214148afJeff Brown    /**
16611417b1cfde8f1749905f2d735623af9214148afJeff Brown     * Gets the route that this dialog is controlling.
16711417b1cfde8f1749905f2d735623af9214148afJeff Brown     */
16811417b1cfde8f1749905f2d735623af9214148afJeff Brown    public MediaRouter.RouteInfo getRoute() {
16911417b1cfde8f1749905f2d735623af9214148afJeff Brown        return mRoute;
17011417b1cfde8f1749905f2d735623af9214148afJeff Brown    }
17111417b1cfde8f1749905f2d735623af9214148afJeff Brown
1726051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo    private MediaRouter.RouteGroup getGroup() {
1736051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo        if (mRoute instanceof MediaRouter.RouteGroup) {
1746051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo            return (MediaRouter.RouteGroup) mRoute;
1756051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo        }
1766051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo        return null;
1776051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo    }
1786051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo
17911417b1cfde8f1749905f2d735623af9214148afJeff Brown    /**
18011417b1cfde8f1749905f2d735623af9214148afJeff Brown     * Provides the subclass an opportunity to create a view that will
18111417b1cfde8f1749905f2d735623af9214148afJeff Brown     * be included within the body of the dialog to offer additional media controls
18211417b1cfde8f1749905f2d735623af9214148afJeff Brown     * for the currently playing content.
18311417b1cfde8f1749905f2d735623af9214148afJeff Brown     *
18411417b1cfde8f1749905f2d735623af9214148afJeff Brown     * @param savedInstanceState The dialog's saved instance state.
18511417b1cfde8f1749905f2d735623af9214148afJeff Brown     * @return The media control view, or null if none.
18611417b1cfde8f1749905f2d735623af9214148afJeff Brown     */
18711417b1cfde8f1749905f2d735623af9214148afJeff Brown    public View onCreateMediaControlView(Bundle savedInstanceState) {
18811417b1cfde8f1749905f2d735623af9214148afJeff Brown        return null;
18911417b1cfde8f1749905f2d735623af9214148afJeff Brown    }
19011417b1cfde8f1749905f2d735623af9214148afJeff Brown
19111417b1cfde8f1749905f2d735623af9214148afJeff Brown    /**
19211417b1cfde8f1749905f2d735623af9214148afJeff Brown     * Gets the media control view that was created by {@link #onCreateMediaControlView(Bundle)}.
19311417b1cfde8f1749905f2d735623af9214148afJeff Brown     *
19411417b1cfde8f1749905f2d735623af9214148afJeff Brown     * @return The media control view, or null if none.
19511417b1cfde8f1749905f2d735623af9214148afJeff Brown     */
19611417b1cfde8f1749905f2d735623af9214148afJeff Brown    public View getMediaControlView() {
1977ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim        return mCustomControlView;
19811417b1cfde8f1749905f2d735623af9214148afJeff Brown    }
19911417b1cfde8f1749905f2d735623af9214148afJeff Brown
200eff7719415542ba819054863b0995f07742a7a8aJeff Brown    /**
201f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah     * Sets whether to enable the volume slider and volume control using the volume keys
202f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah     * when the route supports it.
203f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah     * <p>
204f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah     * The default value is true.
205f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah     * </p>
206f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah     */
207f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah    public void setVolumeControlEnabled(boolean enable) {
208f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah        if (mVolumeControlEnabled != enable) {
209f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah            mVolumeControlEnabled = enable;
210f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah            if (mCreated) {
2111ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                updateVolumeControl();
212f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah            }
213f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah        }
214f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah    }
215f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah
216f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah    /**
217f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah     * Returns whether to enable the volume slider and volume control using the volume keys
218f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah     * when the route supports it.
219f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah     */
220f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah    public boolean isVolumeControlEnabled() {
221f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah        return mVolumeControlEnabled;
222f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah    }
223f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah
224f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah    /**
22594be6100218126ce6a08bf1f56209578500b361fRoboErik     * Set the session to use for metadata and transport controls. The dialog
22694be6100218126ce6a08bf1f56209578500b361fRoboErik     * will listen to changes on this session and update the UI automatically in
22794be6100218126ce6a08bf1f56209578500b361fRoboErik     * response to changes.
22894be6100218126ce6a08bf1f56209578500b361fRoboErik     *
22994be6100218126ce6a08bf1f56209578500b361fRoboErik     * @param sessionToken The token for the session to use.
230eff7719415542ba819054863b0995f07742a7a8aJeff Brown     */
231e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik    private void setMediaSession(MediaSessionCompat.Token sessionToken) {
23294be6100218126ce6a08bf1f56209578500b361fRoboErik        if (mMediaController != null) {
23394be6100218126ce6a08bf1f56209578500b361fRoboErik            mMediaController.unregisterCallback(mControllerCallback);
23494be6100218126ce6a08bf1f56209578500b361fRoboErik            mMediaController = null;
23594be6100218126ce6a08bf1f56209578500b361fRoboErik        }
23694be6100218126ce6a08bf1f56209578500b361fRoboErik        if (sessionToken == null) {
23794be6100218126ce6a08bf1f56209578500b361fRoboErik            return;
23894be6100218126ce6a08bf1f56209578500b361fRoboErik        }
239e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik        if (!mAttachedToWindow) {
240e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik            return;
241e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik        }
24294be6100218126ce6a08bf1f56209578500b361fRoboErik        try {
24394be6100218126ce6a08bf1f56209578500b361fRoboErik            mMediaController = new MediaControllerCompat(getContext(), sessionToken);
24494be6100218126ce6a08bf1f56209578500b361fRoboErik        } catch (RemoteException e) {
24594be6100218126ce6a08bf1f56209578500b361fRoboErik            Log.e(TAG, "Error creating media controller in setMediaSession.", e);
24694be6100218126ce6a08bf1f56209578500b361fRoboErik        }
24794be6100218126ce6a08bf1f56209578500b361fRoboErik        if (mMediaController != null) {
24894be6100218126ce6a08bf1f56209578500b361fRoboErik            mMediaController.registerCallback(mControllerCallback);
249eff7719415542ba819054863b0995f07742a7a8aJeff Brown        }
25094be6100218126ce6a08bf1f56209578500b361fRoboErik        MediaMetadataCompat metadata = mMediaController == null ? null
25194be6100218126ce6a08bf1f56209578500b361fRoboErik                : mMediaController.getMetadata();
25294be6100218126ce6a08bf1f56209578500b361fRoboErik        mDescription = metadata == null ? null : metadata.getDescription();
25394be6100218126ce6a08bf1f56209578500b361fRoboErik        mState = mMediaController == null ? null : mMediaController.getPlaybackState();
25494be6100218126ce6a08bf1f56209578500b361fRoboErik        update();
255eff7719415542ba819054863b0995f07742a7a8aJeff Brown    }
256eff7719415542ba819054863b0995f07742a7a8aJeff Brown
257eff7719415542ba819054863b0995f07742a7a8aJeff Brown    /**
25875dbda46b4ca20861e9d382b1662b3c34d20da8aInsun Kang     * Gets the session to use for metadata and transport controls.
25994be6100218126ce6a08bf1f56209578500b361fRoboErik     *
26075dbda46b4ca20861e9d382b1662b3c34d20da8aInsun Kang     * @return The token for the session to use or null if none.
261eff7719415542ba819054863b0995f07742a7a8aJeff Brown     */
26294be6100218126ce6a08bf1f56209578500b361fRoboErik    public MediaSessionCompat.Token getMediaSession() {
26394be6100218126ce6a08bf1f56209578500b361fRoboErik        return mMediaController == null ? null : mMediaController.getSessionToken();
264eff7719415542ba819054863b0995f07742a7a8aJeff Brown    }
265eff7719415542ba819054863b0995f07742a7a8aJeff Brown
26611417b1cfde8f1749905f2d735623af9214148afJeff Brown    @Override
26711417b1cfde8f1749905f2d735623af9214148afJeff Brown    protected void onCreate(Bundle savedInstanceState) {
26811417b1cfde8f1749905f2d735623af9214148afJeff Brown        super.onCreate(savedInstanceState);
26911417b1cfde8f1749905f2d735623af9214148afJeff Brown
270a09c7b30d3a5c53281db955eabce171e1aec6feaSungsoo Lim        setContentView(R.layout.mr_controller_material_dialog_b);
271f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seo
27206991009e52024cbb3dde550988e06149e77a269Jae Seo        // Remove the neutral button.
27306991009e52024cbb3dde550988e06149e77a269Jae Seo        findViewById(BUTTON_NEUTRAL_RES_ID).setVisibility(View.GONE);
27406991009e52024cbb3dde550988e06149e77a269Jae Seo
27594be6100218126ce6a08bf1f56209578500b361fRoboErik        ClickListener listener = new ClickListener();
276d6748a7926ebb2450337f9f0ff4d445c980344e5Jeff Brown
27706991009e52024cbb3dde550988e06149e77a269Jae Seo        mDisconnectButton = (Button) findViewById(BUTTON_DISCONNECT_RES_ID);
27806991009e52024cbb3dde550988e06149e77a269Jae Seo        mDisconnectButton.setText(R.string.mr_controller_disconnect);
27994be6100218126ce6a08bf1f56209578500b361fRoboErik        mDisconnectButton.setOnClickListener(listener);
28011417b1cfde8f1749905f2d735623af9214148afJeff Brown
28106991009e52024cbb3dde550988e06149e77a269Jae Seo        mStopCastingButton = (Button) findViewById(BUTTON_STOP_RES_ID);
28206991009e52024cbb3dde550988e06149e77a269Jae Seo        mStopCastingButton.setText(R.string.mr_controller_stop);
28394be6100218126ce6a08bf1f56209578500b361fRoboErik        mStopCastingButton.setOnClickListener(listener);
28411417b1cfde8f1749905f2d735623af9214148afJeff Brown
28506991009e52024cbb3dde550988e06149e77a269Jae Seo        TypedValue value = new TypedValue();
28606991009e52024cbb3dde550988e06149e77a269Jae Seo        if (getContext().getTheme().resolveAttribute(R.attr.colorPrimary, value, true)) {
28706991009e52024cbb3dde550988e06149e77a269Jae Seo            mDisconnectButton.setTextColor(value.data);
28806991009e52024cbb3dde550988e06149e77a269Jae Seo            mStopCastingButton.setTextColor(value.data);
28906991009e52024cbb3dde550988e06149e77a269Jae Seo        }
29006991009e52024cbb3dde550988e06149e77a269Jae Seo
2911ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim        mRouteNameTextView = (TextView) findViewById(R.id.mr_name);
2921ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim        mCloseButton = (ImageButton) findViewById(R.id.mr_close);
293b48ccf48b0281e69262fc643d0def898aede407bSungsoo Lim        mCloseButton.setOnClickListener(listener);
2941ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim        mCustomControlLayout = (FrameLayout) findViewById(R.id.mr_custom_control);
2952b274bd3e06bd33c9b2a0851256afcda94d96395Dongwon Kang        mDefaultControlLayout = (FrameLayout) findViewById(R.id.mr_default_control);
2967ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim        mArtView = (ImageView) findViewById(R.id.mr_art);
2976051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo
2988e1281a26eaabd6422fd84c11010134a0a9c3338Jaewan Kim        mMediaControlLayout = (LinearLayout) findViewById(R.id.mr_media_control);
2992c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim        mMediaMainControlLayout = (LinearLayout) findViewById(R.id.mr_media_main_control);
3001ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim        mDividerView = findViewById(R.id.mr_control_divider);
3011ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim
3021ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim        mPlaybackControl = (RelativeLayout) findViewById(R.id.mr_playback_control);
3031ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim        mTitleView = (TextView) findViewById(R.id.mr_control_title);
3041ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim        mSubtitleView = (TextView) findViewById(R.id.mr_control_subtitle);
3051ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim        mPlayPauseButton = (ImageButton) findViewById(R.id.mr_control_play_pause);
3061ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim        mPlayPauseButton.setOnClickListener(listener);
3071ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim
3081ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim        mVolumeControl = (LinearLayout) findViewById(R.id.mr_volume_control);
3091ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim        mVolumeSlider = (SeekBar) findViewById(R.id.mr_volume_slider);
310435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim        mVolumeSlider.setTag(VOLUME_SLIDER_TAG_MASTER);
311435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim        mVolumeChangeListener = new VolumeChangeListener();
312435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim        mVolumeSlider.setOnSeekBarChangeListener(mVolumeChangeListener);
3131ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim
314328f1006c17ddeb3eb563580bcd6638e1cfb4320Jaewan Kim        mVolumeGroupList = (ListView) findViewById(R.id.mr_volume_group_list);
315328f1006c17ddeb3eb563580bcd6638e1cfb4320Jaewan Kim        mGroupExpandCollapseButton =
316328f1006c17ddeb3eb563580bcd6638e1cfb4320Jaewan Kim                (MediaRouteExpandCollapseButton) findViewById(R.id.mr_group_expand_collapse);
3171ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim        mGroupExpandCollapseButton.setOnClickListener(new View.OnClickListener() {
3181ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim            @Override
3191ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim            public void onClick(View v) {
3202b274bd3e06bd33c9b2a0851256afcda94d96395Dongwon Kang                mIsGroupExpanded = !mIsGroupExpanded;
3212b274bd3e06bd33c9b2a0851256afcda94d96395Dongwon Kang                if (mIsGroupExpanded) {
3221ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                    mVolumeGroupList.setVisibility(View.VISIBLE);
3231ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                    mVolumeGroupList.setAdapter(
3241ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                            new VolumeGroupAdapter(getContext(), getGroup().getRoutes()));
3251ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                } else {
3261ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                    mVolumeGroupList.setVisibility(View.GONE);
3271ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                }
3282c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim                updateLayoutHeight();
3291ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim            }
3301ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim        });
33111417b1cfde8f1749905f2d735623af9214148afJeff Brown
3327ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim        mCustomControlView = onCreateMediaControlView(savedInstanceState);
3337ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim        if (mCustomControlView != null) {
3341ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim            mCustomControlLayout.addView(mCustomControlView);
3351ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim            mCustomControlLayout.setVisibility(View.VISIBLE);
3367ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim            mArtView.setVisibility(View.GONE);
33711417b1cfde8f1749905f2d735623af9214148afJeff Brown        }
33886a802c8d09983d8725cccf59217e65d3e0c6373Jae Seo        mCreated = true;
339d52e30f3736a821e45266c28c334756f5f7e55c3Jae Seo        updateLayout();
340d52e30f3736a821e45266c28c334756f5f7e55c3Jae Seo    }
341d52e30f3736a821e45266c28c334756f5f7e55c3Jae Seo
342d52e30f3736a821e45266c28c334756f5f7e55c3Jae Seo    /**
343d52e30f3736a821e45266c28c334756f5f7e55c3Jae Seo     * Sets the width of the dialog. Also called when configuration changes.
344d52e30f3736a821e45266c28c334756f5f7e55c3Jae Seo     */
345d52e30f3736a821e45266c28c334756f5f7e55c3Jae Seo    void updateLayout() {
346d52e30f3736a821e45266c28c334756f5f7e55c3Jae Seo        int width = MediaRouteDialogHelper.getDialogWidth(getContext());
347d52e30f3736a821e45266c28c334756f5f7e55c3Jae Seo        getWindow().setLayout(width, ViewGroup.LayoutParams.WRAP_CONTENT);
348d52e30f3736a821e45266c28c334756f5f7e55c3Jae Seo
349d52e30f3736a821e45266c28c334756f5f7e55c3Jae Seo        View decorView = getWindow().getDecorView();
350d52e30f3736a821e45266c28c334756f5f7e55c3Jae Seo        mDialogContentWidth = width - decorView.getPaddingLeft() - decorView.getPaddingRight();
351d52e30f3736a821e45266c28c334756f5f7e55c3Jae Seo
352c5738b858579021cc89fffd8a891b4c5ea8c0f83Jaewan Kim        Resources res = getContext().getResources();
353c5738b858579021cc89fffd8a891b4c5ea8c0f83Jaewan Kim        mVolumeGroupListItemIconSize = res.getDimensionPixelSize(
354c5738b858579021cc89fffd8a891b4c5ea8c0f83Jaewan Kim                R.dimen.mr_controller_volume_group_list_item_icon_size);
355c5738b858579021cc89fffd8a891b4c5ea8c0f83Jaewan Kim        mVolumeGroupListItemHeight = res.getDimensionPixelSize(
356c5738b858579021cc89fffd8a891b4c5ea8c0f83Jaewan Kim                R.dimen.mr_controller_volume_group_list_item_height);
357c5738b858579021cc89fffd8a891b4c5ea8c0f83Jaewan Kim        mVolumeGroupListMaxHeight = res.getDimensionPixelSize(
358c5738b858579021cc89fffd8a891b4c5ea8c0f83Jaewan Kim                R.dimen.mr_controller_volume_group_list_max_height);
359c5738b858579021cc89fffd8a891b4c5ea8c0f83Jaewan Kim
360c74ed2dfd8328da1f1786f1e4fb07f0e8eebd35bJae Seo        // Ensure the mArtView is updated.
361c74ed2dfd8328da1f1786f1e4fb07f0e8eebd35bJae Seo        mArtIconBitmap = null;
362c74ed2dfd8328da1f1786f1e4fb07f0e8eebd35bJae Seo        mArtIconUri = null;
3637ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim        update();
36411417b1cfde8f1749905f2d735623af9214148afJeff Brown    }
36511417b1cfde8f1749905f2d735623af9214148afJeff Brown
36611417b1cfde8f1749905f2d735623af9214148afJeff Brown    @Override
36711417b1cfde8f1749905f2d735623af9214148afJeff Brown    public void onAttachedToWindow() {
36811417b1cfde8f1749905f2d735623af9214148afJeff Brown        super.onAttachedToWindow();
369e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik        mAttachedToWindow = true;
37011417b1cfde8f1749905f2d735623af9214148afJeff Brown
37111417b1cfde8f1749905f2d735623af9214148afJeff Brown        mRouter.addCallback(MediaRouteSelector.EMPTY, mCallback,
37211417b1cfde8f1749905f2d735623af9214148afJeff Brown                MediaRouter.CALLBACK_FLAG_UNFILTERED_EVENTS);
373e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik        setMediaSession(mRouter.getMediaSessionToken());
37411417b1cfde8f1749905f2d735623af9214148afJeff Brown    }
37511417b1cfde8f1749905f2d735623af9214148afJeff Brown
37611417b1cfde8f1749905f2d735623af9214148afJeff Brown    @Override
37711417b1cfde8f1749905f2d735623af9214148afJeff Brown    public void onDetachedFromWindow() {
37811417b1cfde8f1749905f2d735623af9214148afJeff Brown        mRouter.removeCallback(mCallback);
379e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik        setMediaSession(null);
380e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik        mAttachedToWindow = false;
38111417b1cfde8f1749905f2d735623af9214148afJeff Brown        super.onDetachedFromWindow();
38211417b1cfde8f1749905f2d735623af9214148afJeff Brown    }
38311417b1cfde8f1749905f2d735623af9214148afJeff Brown
38411417b1cfde8f1749905f2d735623af9214148afJeff Brown    @Override
38511417b1cfde8f1749905f2d735623af9214148afJeff Brown    public boolean onKeyDown(int keyCode, KeyEvent event) {
386ce8cbd614a64f94e54b936d66ecd14b6c1282ddfJeff Brown        if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN
387ce8cbd614a64f94e54b936d66ecd14b6c1282ddfJeff Brown                || keyCode == KeyEvent.KEYCODE_VOLUME_UP) {
388ce8cbd614a64f94e54b936d66ecd14b6c1282ddfJeff Brown            mRoute.requestUpdateVolume(keyCode == KeyEvent.KEYCODE_VOLUME_DOWN ? -1 : 1);
389ce8cbd614a64f94e54b936d66ecd14b6c1282ddfJeff Brown            return true;
39011417b1cfde8f1749905f2d735623af9214148afJeff Brown        }
39111417b1cfde8f1749905f2d735623af9214148afJeff Brown        return super.onKeyDown(keyCode, event);
39211417b1cfde8f1749905f2d735623af9214148afJeff Brown    }
39311417b1cfde8f1749905f2d735623af9214148afJeff Brown
39411417b1cfde8f1749905f2d735623af9214148afJeff Brown    @Override
39511417b1cfde8f1749905f2d735623af9214148afJeff Brown    public boolean onKeyUp(int keyCode, KeyEvent event) {
396ce8cbd614a64f94e54b936d66ecd14b6c1282ddfJeff Brown        if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN
397ce8cbd614a64f94e54b936d66ecd14b6c1282ddfJeff Brown                || keyCode == KeyEvent.KEYCODE_VOLUME_UP) {
398ce8cbd614a64f94e54b936d66ecd14b6c1282ddfJeff Brown            return true;
39911417b1cfde8f1749905f2d735623af9214148afJeff Brown        }
40011417b1cfde8f1749905f2d735623af9214148afJeff Brown        return super.onKeyUp(keyCode, event);
40111417b1cfde8f1749905f2d735623af9214148afJeff Brown    }
40211417b1cfde8f1749905f2d735623af9214148afJeff Brown
4037ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim    private void update() {
40411417b1cfde8f1749905f2d735623af9214148afJeff Brown        if (!mRoute.isSelected() || mRoute.isDefault()) {
40511417b1cfde8f1749905f2d735623af9214148afJeff Brown            dismiss();
4067ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim            return;
40711417b1cfde8f1749905f2d735623af9214148afJeff Brown        }
40894be6100218126ce6a08bf1f56209578500b361fRoboErik        if (!mCreated) {
4097ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim            return;
41094be6100218126ce6a08bf1f56209578500b361fRoboErik        }
4112ef36d857302c5cd738c7c8bdec53d31feebebbaJeff Brown
4127ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim        mRouteNameTextView.setText(mRoute.getName());
41306991009e52024cbb3dde550988e06149e77a269Jae Seo        mDisconnectButton.setVisibility(mRoute.canDisconnect() ? View.VISIBLE : View.GONE);
41494be6100218126ce6a08bf1f56209578500b361fRoboErik
4157ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim        if (mCustomControlView == null) {
416005482649154d0970693b3967241eb4d2cb22003Jaewan Kim            if (mFetchArtTask != null) {
417005482649154d0970693b3967241eb4d2cb22003Jaewan Kim                mFetchArtTask.cancel(true);
41866937fc7dfe22c8c505bf735781d1f5b62f08e34Dongwon Kang            }
419005482649154d0970693b3967241eb4d2cb22003Jaewan Kim            mFetchArtTask = new FetchArtTask();
420005482649154d0970693b3967241eb4d2cb22003Jaewan Kim            mFetchArtTask.execute();
421f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah        }
4221ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim        updateVolumeControl();
4231ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim        updatePlaybackControl();
4241ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim    }
4251ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim
4262c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim    private boolean isPlaybackControlAvailable() {
4272c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim        return mCustomControlView == null && (mDescription != null || mState != null);
4282c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim    }
4292c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim
4303fbf2b99dc391c331c2a816e13222a700a1f6dd5Jaewan Kim    /**
4313fbf2b99dc391c331c2a816e13222a700a1f6dd5Jaewan Kim     * Returns the height of main media controller which includes playback control and master
4323fbf2b99dc391c331c2a816e13222a700a1f6dd5Jaewan Kim     * volume control.
4333fbf2b99dc391c331c2a816e13222a700a1f6dd5Jaewan Kim     */
4342c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim    private int getMainControllerHeight(boolean showPlaybackControl) {
4352c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim        int height = 0;
4362c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim        if (showPlaybackControl || mVolumeControl.getVisibility() == View.VISIBLE) {
4372c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim            height += mMediaMainControlLayout.getPaddingTop()
4382c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim                    + mMediaMainControlLayout.getPaddingBottom();
4392c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim            if (showPlaybackControl) {
4402c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim                height +=  mPlaybackControl.getMeasuredHeight();
4412c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim            }
4422c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim            if (mVolumeControl.getVisibility() == View.VISIBLE) {
4432c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim                height += mVolumeControl.getMeasuredHeight();
4442c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim            }
4452c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim            if (showPlaybackControl && mVolumeControl.getVisibility() == View.VISIBLE) {
4462c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim                height += mDividerView.getMeasuredHeight();
4472c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim            }
4482c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim        }
4492c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim        return height;
4502c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim    }
4512c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim
452aaa885dc21bf5f526e1d3897e26ade96e1fae9ccJaewan Kim    private void updateMediaControlVisibility(boolean showPlaybackControl) {
45392fa1536ded1a81a2b054a08d72b591a13293f99Dongwon Kang        // TODO: Update the top and bottom padding of the control layout according to the display
45492fa1536ded1a81a2b054a08d72b591a13293f99Dongwon Kang        // height.
45592fa1536ded1a81a2b054a08d72b591a13293f99Dongwon Kang        mDividerView.setVisibility((mVolumeControl.getVisibility() == View.VISIBLE
456aaa885dc21bf5f526e1d3897e26ade96e1fae9ccJaewan Kim                && showPlaybackControl) ? View.VISIBLE : View.GONE);
45792fa1536ded1a81a2b054a08d72b591a13293f99Dongwon Kang        mMediaControlLayout.setVisibility((mVolumeControl.getVisibility() == View.GONE
458f8e1601db320e5bde6cb5ddcd4ecea187e3d4362Sungsoo Lim                && !showPlaybackControl) ? View.GONE : View.VISIBLE);
45986dcb627078ea297c4337ed634fc3fe874e23897Jae Seo    }
46086dcb627078ea297c4337ed634fc3fe874e23897Jae Seo
46186dcb627078ea297c4337ed634fc3fe874e23897Jae Seo    private void updateLayoutHeight() {
46286dcb627078ea297c4337ed634fc3fe874e23897Jae Seo        // We need to defer the update until the first layout has occurred, as we don't yet know the
46386dcb627078ea297c4337ed634fc3fe874e23897Jae Seo        // overall visible display size in which the window this view is attached to has been
46486dcb627078ea297c4337ed634fc3fe874e23897Jae Seo        // positioned in.
46586dcb627078ea297c4337ed634fc3fe874e23897Jae Seo        ViewTreeObserver observer = mDefaultControlLayout.getViewTreeObserver();
46686dcb627078ea297c4337ed634fc3fe874e23897Jae Seo        observer.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
46786dcb627078ea297c4337ed634fc3fe874e23897Jae Seo            @Override
46886dcb627078ea297c4337ed634fc3fe874e23897Jae Seo            public void onGlobalLayout() {
46986dcb627078ea297c4337ed634fc3fe874e23897Jae Seo                mDefaultControlLayout.getViewTreeObserver().removeGlobalOnLayoutListener(this);
47086dcb627078ea297c4337ed634fc3fe874e23897Jae Seo                updateLayoutHeightInternal();
47186dcb627078ea297c4337ed634fc3fe874e23897Jae Seo            }
47286dcb627078ea297c4337ed634fc3fe874e23897Jae Seo        });
47392fa1536ded1a81a2b054a08d72b591a13293f99Dongwon Kang    }
47492fa1536ded1a81a2b054a08d72b591a13293f99Dongwon Kang
4753fbf2b99dc391c331c2a816e13222a700a1f6dd5Jaewan Kim    /**
4763fbf2b99dc391c331c2a816e13222a700a1f6dd5Jaewan Kim     * Updates the height of views and hide artwork or metadata if space is limited.
4773fbf2b99dc391c331c2a816e13222a700a1f6dd5Jaewan Kim     */
47886dcb627078ea297c4337ed634fc3fe874e23897Jae Seo    private void updateLayoutHeightInternal() {
4792c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim        if (mCustomControlView != null) {
4802c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim            return;
4812c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim        }
482aaa885dc21bf5f526e1d3897e26ade96e1fae9ccJaewan Kim        updateMediaControlVisibility(isPlaybackControlAvailable());
4832c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim        View decorView = getWindow().getDecorView();
4842c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim        decorView.measure(
4852c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim                MeasureSpec.makeMeasureSpec(getWindow().getAttributes().width, MeasureSpec.EXACTLY),
4862c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim                MeasureSpec.UNSPECIFIED);
4872c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim        int artViewHeight = 0;
4882c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim        if (mArtView.getDrawable() instanceof BitmapDrawable) {
4892c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim            Bitmap art = ((BitmapDrawable) mArtView.getDrawable()).getBitmap();
4902c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim            if (art != null) {
4912c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim                artViewHeight = getDesiredArtHeight(art.getWidth(), art.getHeight());
4922c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim                mArtView.setScaleType(art.getWidth() >= art.getHeight()
4932c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim                        ? ImageView.ScaleType.FIT_XY : ImageView.ScaleType.FIT_CENTER);
4942c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim            }
4952c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim        }
4962c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim        int mainControllerHeight = getMainControllerHeight(isPlaybackControlAvailable());
4972c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim        int volumeGroupListCount = mVolumeGroupList.getVisibility() == View.VISIBLE
4982c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim                ? mVolumeGroupList.getAdapter().getCount() : 0;
499c5738b858579021cc89fffd8a891b4c5ea8c0f83Jaewan Kim        // Scale down volume group list items in landscape mode.
500c5738b858579021cc89fffd8a891b4c5ea8c0f83Jaewan Kim        for (int i = 0; i < volumeGroupListCount; i++) {
501c5738b858579021cc89fffd8a891b4c5ea8c0f83Jaewan Kim            View item = mVolumeGroupList.getChildAt(i);
502c5738b858579021cc89fffd8a891b4c5ea8c0f83Jaewan Kim            if (item != null) {
503c5738b858579021cc89fffd8a891b4c5ea8c0f83Jaewan Kim                setLayoutHeight(item, mVolumeGroupListItemHeight);
504c5738b858579021cc89fffd8a891b4c5ea8c0f83Jaewan Kim                setLayoutHeight(item.findViewById(R.id.mr_volume_item_icon),
505c5738b858579021cc89fffd8a891b4c5ea8c0f83Jaewan Kim                        mVolumeGroupListItemIconSize);
506c5738b858579021cc89fffd8a891b4c5ea8c0f83Jaewan Kim            }
507c5738b858579021cc89fffd8a891b4c5ea8c0f83Jaewan Kim        }
50840181af8431b704013f596a5ac298a06174d4d82Jaewan Kim        int volumeGroupHeight = (volumeGroupListCount == 0) ? 0
509c5738b858579021cc89fffd8a891b4c5ea8c0f83Jaewan Kim                : mVolumeGroupListItemHeight * volumeGroupListCount + mVolumeGroupListPaddingTop;
51019d268075834665bf62567b224dcd3549c92d3c3Jae Seo        volumeGroupHeight = Math.min(volumeGroupHeight, mVolumeGroupListMaxHeight);
51119d268075834665bf62567b224dcd3549c92d3c3Jae Seo
5128367dca195f881c38fbaf69a5d533a6cca820471Jaewan Kim        int desiredControlLayoutHeight =
5132c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim                Math.max(artViewHeight, volumeGroupHeight) + mainControllerHeight;
5142c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim        Rect visibleRect = new Rect();
5152c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim        decorView.getWindowVisibleDisplayFrame(visibleRect);
5162c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim        // Height of non-control views in decor view.
5172c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim        // This includes title bar, button bar, and dialog's vertical padding which should be
5182c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim        // always shown.
5192c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim        int nonControlViewHeight = decorView.getMeasuredHeight()
5202c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim                - mDefaultControlLayout.getMeasuredHeight();
5212c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim        // Maximum allowed height for controls to fit screen.
5222c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim        int maximumControlViewHeight = visibleRect.height() - nonControlViewHeight;
5232c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim
5243fbf2b99dc391c331c2a816e13222a700a1f6dd5Jaewan Kim        // Show artwork if it fits the screen and expanded volume group list has fewer than 3 items.
5253fbf2b99dc391c331c2a816e13222a700a1f6dd5Jaewan Kim        if (artViewHeight > 0 && volumeGroupListCount < 3
5268367dca195f881c38fbaf69a5d533a6cca820471Jaewan Kim                && desiredControlLayoutHeight <= maximumControlViewHeight) {
5272c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim            mArtView.setVisibility(View.VISIBLE);
5282c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim            setLayoutHeight(mArtView, artViewHeight);
5292c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim        } else {
5302c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim            mArtView.setVisibility(View.GONE);
5312c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim            artViewHeight = 0;
5328367dca195f881c38fbaf69a5d533a6cca820471Jaewan Kim            desiredControlLayoutHeight = volumeGroupHeight + mainControllerHeight;
5332c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim        }
5342c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim        // Show control if it fits the screen
5352c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim        if (isPlaybackControlAvailable()
5368367dca195f881c38fbaf69a5d533a6cca820471Jaewan Kim                && desiredControlLayoutHeight <= maximumControlViewHeight) {
5372c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim            mPlaybackControl.setVisibility(View.VISIBLE);
5382c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim        } else {
5392c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim            mPlaybackControl.setVisibility(View.GONE);
5402c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim        }
541aaa885dc21bf5f526e1d3897e26ade96e1fae9ccJaewan Kim        updateMediaControlVisibility(mPlaybackControl.getVisibility() == View.VISIBLE);
5422c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim        mainControllerHeight = getMainControllerHeight(
5432c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim                mPlaybackControl.getVisibility() == View.VISIBLE);
5448367dca195f881c38fbaf69a5d533a6cca820471Jaewan Kim        desiredControlLayoutHeight =
5452c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim                Math.max(artViewHeight, volumeGroupHeight) + mainControllerHeight;
5462c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim
5472c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim        // Limit the volume group list height to fit the screen.
5488367dca195f881c38fbaf69a5d533a6cca820471Jaewan Kim        if (desiredControlLayoutHeight > maximumControlViewHeight) {
5498367dca195f881c38fbaf69a5d533a6cca820471Jaewan Kim            volumeGroupHeight -= (desiredControlLayoutHeight - maximumControlViewHeight);
5508367dca195f881c38fbaf69a5d533a6cca820471Jaewan Kim            desiredControlLayoutHeight = maximumControlViewHeight;
5512c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim        }
5522c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim        setLayoutHeight(mVolumeGroupList, volumeGroupHeight);
5538367dca195f881c38fbaf69a5d533a6cca820471Jaewan Kim        setLayoutHeight(mDefaultControlLayout, desiredControlLayoutHeight);
5542c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim    }
5552c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim
5561ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim    private void updateVolumeControl() {
5571ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim        if (!mVolumeSliderTouched) {
5587447b1958129579090ee279caac7d703dba2ad28Sungsoo Lim            if (isVolumeControlAvailable(mRoute)) {
5591ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                mVolumeControl.setVisibility(View.VISIBLE);
5601ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                mVolumeSlider.setMax(mRoute.getVolumeMax());
5611ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                mVolumeSlider.setProgress(mRoute.getVolume());
562050b7ec33bd9a2fe493f0b0b85d49ed213046219Jae Seo                if (getGroup() == null) {
563050b7ec33bd9a2fe493f0b0b85d49ed213046219Jae Seo                    mGroupExpandCollapseButton.setVisibility(View.GONE);
564050b7ec33bd9a2fe493f0b0b85d49ed213046219Jae Seo                } else {
565050b7ec33bd9a2fe493f0b0b85d49ed213046219Jae Seo                    mGroupExpandCollapseButton.setVisibility(View.VISIBLE);
566050b7ec33bd9a2fe493f0b0b85d49ed213046219Jae Seo                    VolumeGroupAdapter adapter =
567050b7ec33bd9a2fe493f0b0b85d49ed213046219Jae Seo                            (VolumeGroupAdapter) mVolumeGroupList.getAdapter();
568050b7ec33bd9a2fe493f0b0b85d49ed213046219Jae Seo                    if (adapter != null) {
569050b7ec33bd9a2fe493f0b0b85d49ed213046219Jae Seo                        adapter.notifyDataSetChanged();
5701ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                    }
5711ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                }
5721ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim            } else {
5731ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                mVolumeControl.setVisibility(View.GONE);
5741ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim            }
5752c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim            updateLayoutHeight();
5767447b1958129579090ee279caac7d703dba2ad28Sungsoo Lim        } else if (mVolumeControl.getVisibility() == View.VISIBLE) {
5777447b1958129579090ee279caac7d703dba2ad28Sungsoo Lim            mVolumeSlider.setProgress(mRoute.getVolume());
5787447b1958129579090ee279caac7d703dba2ad28Sungsoo Lim            if (mIsGroupExpanded) {
5797447b1958129579090ee279caac7d703dba2ad28Sungsoo Lim                for (int i = 0; i < mVolumeGroupList.getChildCount(); ++i) {
5807447b1958129579090ee279caac7d703dba2ad28Sungsoo Lim                    MediaRouter.RouteInfo route = getGroup().getRouteAt(i);
5817447b1958129579090ee279caac7d703dba2ad28Sungsoo Lim                    if (isVolumeControlAvailable(route)) {
5827447b1958129579090ee279caac7d703dba2ad28Sungsoo Lim                        SeekBar volumeSlider = (SeekBar) mVolumeGroupList.getChildAt(i)
5837447b1958129579090ee279caac7d703dba2ad28Sungsoo Lim                                .findViewById(R.id.mr_volume_slider);
5847447b1958129579090ee279caac7d703dba2ad28Sungsoo Lim                        volumeSlider.setProgress(route.getVolume());
5857447b1958129579090ee279caac7d703dba2ad28Sungsoo Lim                    }
5867447b1958129579090ee279caac7d703dba2ad28Sungsoo Lim                }
5877447b1958129579090ee279caac7d703dba2ad28Sungsoo Lim            }
5881ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim        }
5891ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim    }
5901ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim
5911ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim    private void updatePlaybackControl() {
5922c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim        if (isPlaybackControlAvailable()) {
5931ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim            CharSequence title = mDescription == null ? null : mDescription.getTitle();
5941ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim            boolean hasTitle = !TextUtils.isEmpty(title);
5951ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim
5961ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim            CharSequence subtitle = mDescription == null ? null : mDescription.getSubtitle();
5971ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim            boolean hasSubtitle = !TextUtils.isEmpty(subtitle);
5981ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim
5998fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang            boolean showTitle = false;
6008fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang            boolean showSubtitle = false;
6018fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang            if (mRoute.getPresentationDisplayId()
6028fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang                    != MediaRouter.RouteInfo.PRESENTATION_DISPLAY_ID_NONE) {
6038fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang                // The user is currently casting screen.
6048fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang                mTitleView.setText(R.string.mr_controller_casting_screen);
6058fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang                showTitle = true;
6068fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang            } else if (mState == null || mState.getState() == PlaybackStateCompat.STATE_NONE) {
6078fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang                mTitleView.setText(R.string.mr_controller_no_media_selected);
6088fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang                showTitle = true;
6098fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang            } else if (!hasTitle && !hasSubtitle) {
6108fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang                mTitleView.setText(R.string.mr_controller_no_info_available);
6118fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang                showTitle = true;
6121ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim            } else {
6138fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang                if (hasTitle) {
6148fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang                    mTitleView.setText(title);
6158fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang                    showTitle = true;
6168fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang                }
6178fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang                if (hasSubtitle) {
6188fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang                    mSubtitleView.setText(subtitle);
6198fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang                    showSubtitle = true;
6208fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang                }
6211ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim            }
6228fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang            mTitleView.setVisibility(showTitle ? View.VISIBLE : View.GONE);
6238fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang            mSubtitleView.setVisibility(showSubtitle ? View.VISIBLE : View.GONE);
6248fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang
6251ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim            if (mState != null) {
6261ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                boolean isPlaying = mState.getState() == PlaybackStateCompat.STATE_BUFFERING
6271ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                        || mState.getState() == PlaybackStateCompat.STATE_PLAYING;
6281ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                boolean supportsPlay = (mState.getActions() & (PlaybackStateCompat.ACTION_PLAY
6291ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                        | PlaybackStateCompat.ACTION_PLAY_PAUSE)) != 0;
6301ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                boolean supportsPause = (mState.getActions() & (PlaybackStateCompat.ACTION_PAUSE
6311ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                        | PlaybackStateCompat.ACTION_PLAY_PAUSE)) != 0;
6321ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                if (isPlaying && supportsPause) {
6331ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                    mPlayPauseButton.setVisibility(View.VISIBLE);
6341ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                    mPlayPauseButton.setImageResource(MediaRouterThemeHelper.getThemeResource(
6351ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                            getContext(), R.attr.mediaRoutePauseDrawable));
6361ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                    mPlayPauseButton.setContentDescription(getContext().getResources()
6371ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                            .getText(R.string.mr_controller_pause));
6381ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                } else if (!isPlaying && supportsPlay) {
6391ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                    mPlayPauseButton.setVisibility(View.VISIBLE);
6401ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                    mPlayPauseButton.setImageResource(MediaRouterThemeHelper.getThemeResource(
6411ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                            getContext(), R.attr.mediaRoutePlayDrawable));
6421ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                    mPlayPauseButton.setContentDescription(getContext().getResources()
6431ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                            .getText(R.string.mr_controller_play));
6441ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                } else {
6451ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                    mPlayPauseButton.setVisibility(View.GONE);
6461ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                }
6471ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim            }
6481ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim        }
6492c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim        updateLayoutHeight();
6502b274bd3e06bd33c9b2a0851256afcda94d96395Dongwon Kang    }
6512b274bd3e06bd33c9b2a0851256afcda94d96395Dongwon Kang
6527447b1958129579090ee279caac7d703dba2ad28Sungsoo Lim    private boolean isVolumeControlAvailable(MediaRouter.RouteInfo route) {
6537447b1958129579090ee279caac7d703dba2ad28Sungsoo Lim        return mVolumeControlEnabled && route.getVolumeHandling()
6547447b1958129579090ee279caac7d703dba2ad28Sungsoo Lim                == MediaRouter.RouteInfo.PLAYBACK_VOLUME_VARIABLE;
655f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah    }
656f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah
657be6358a7c928a09f2c767524299f86a8aad84558Dongwon Kang    private static void setLayoutHeight(View view, int height) {
658be6358a7c928a09f2c767524299f86a8aad84558Dongwon Kang        ViewGroup.LayoutParams lp = view.getLayoutParams();
659be6358a7c928a09f2c767524299f86a8aad84558Dongwon Kang        lp.height = height;
660be6358a7c928a09f2c767524299f86a8aad84558Dongwon Kang        view.setLayoutParams(lp);
661be6358a7c928a09f2c767524299f86a8aad84558Dongwon Kang    }
662be6358a7c928a09f2c767524299f86a8aad84558Dongwon Kang
66313d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim    /**
66413d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim     * Returns desired art height to fit into controller dialog.
66513d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim     */
66613d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim    private int getDesiredArtHeight(int originalWidth, int originalHeight) {
66713d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim        if (originalWidth >= originalHeight) {
66813d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim            // For landscape art, fit width to dialog width.
669f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seo            return (int) ((float) mDialogContentWidth * originalHeight / originalWidth + 0.5f);
67013d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim        }
67113d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim        // For portrait art, fit height to 16:9 ratio case's height.
672f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seo        return (int) ((float) mDialogContentWidth * 9 / 16 + 0.5f);
67313d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim    }
67413d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim
67511417b1cfde8f1749905f2d735623af9214148afJeff Brown    private final class MediaRouterCallback extends MediaRouter.Callback {
67611417b1cfde8f1749905f2d735623af9214148afJeff Brown        @Override
67711417b1cfde8f1749905f2d735623af9214148afJeff Brown        public void onRouteUnselected(MediaRouter router, MediaRouter.RouteInfo route) {
67811417b1cfde8f1749905f2d735623af9214148afJeff Brown            update();
67911417b1cfde8f1749905f2d735623af9214148afJeff Brown        }
68011417b1cfde8f1749905f2d735623af9214148afJeff Brown
68111417b1cfde8f1749905f2d735623af9214148afJeff Brown        @Override
68211417b1cfde8f1749905f2d735623af9214148afJeff Brown        public void onRouteChanged(MediaRouter router, MediaRouter.RouteInfo route) {
68311417b1cfde8f1749905f2d735623af9214148afJeff Brown            update();
68411417b1cfde8f1749905f2d735623af9214148afJeff Brown        }
68511417b1cfde8f1749905f2d735623af9214148afJeff Brown
68611417b1cfde8f1749905f2d735623af9214148afJeff Brown        @Override
68711417b1cfde8f1749905f2d735623af9214148afJeff Brown        public void onRouteVolumeChanged(MediaRouter router, MediaRouter.RouteInfo route) {
68811417b1cfde8f1749905f2d735623af9214148afJeff Brown            if (route == mRoute) {
6891ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                updateVolumeControl();
69094be6100218126ce6a08bf1f56209578500b361fRoboErik            }
69194be6100218126ce6a08bf1f56209578500b361fRoboErik        }
69294be6100218126ce6a08bf1f56209578500b361fRoboErik    }
69394be6100218126ce6a08bf1f56209578500b361fRoboErik
69494be6100218126ce6a08bf1f56209578500b361fRoboErik    private final class MediaControllerCallback extends MediaControllerCompat.Callback {
69594be6100218126ce6a08bf1f56209578500b361fRoboErik        @Override
69694be6100218126ce6a08bf1f56209578500b361fRoboErik        public void onSessionDestroyed() {
69794be6100218126ce6a08bf1f56209578500b361fRoboErik            if (mMediaController != null) {
69894be6100218126ce6a08bf1f56209578500b361fRoboErik                mMediaController.unregisterCallback(mControllerCallback);
69994be6100218126ce6a08bf1f56209578500b361fRoboErik                mMediaController = null;
70094be6100218126ce6a08bf1f56209578500b361fRoboErik            }
70194be6100218126ce6a08bf1f56209578500b361fRoboErik        }
70294be6100218126ce6a08bf1f56209578500b361fRoboErik
70394be6100218126ce6a08bf1f56209578500b361fRoboErik        @Override
70494be6100218126ce6a08bf1f56209578500b361fRoboErik        public void onPlaybackStateChanged(PlaybackStateCompat state) {
70594be6100218126ce6a08bf1f56209578500b361fRoboErik            mState = state;
70694be6100218126ce6a08bf1f56209578500b361fRoboErik            update();
70794be6100218126ce6a08bf1f56209578500b361fRoboErik        }
70894be6100218126ce6a08bf1f56209578500b361fRoboErik
70994be6100218126ce6a08bf1f56209578500b361fRoboErik        @Override
71094be6100218126ce6a08bf1f56209578500b361fRoboErik        public void onMetadataChanged(MediaMetadataCompat metadata) {
71194be6100218126ce6a08bf1f56209578500b361fRoboErik            mDescription = metadata == null ? null : metadata.getDescription();
71294be6100218126ce6a08bf1f56209578500b361fRoboErik            update();
71394be6100218126ce6a08bf1f56209578500b361fRoboErik        }
71494be6100218126ce6a08bf1f56209578500b361fRoboErik    }
71594be6100218126ce6a08bf1f56209578500b361fRoboErik
71694be6100218126ce6a08bf1f56209578500b361fRoboErik    private final class ClickListener implements View.OnClickListener {
71794be6100218126ce6a08bf1f56209578500b361fRoboErik        @Override
71894be6100218126ce6a08bf1f56209578500b361fRoboErik        public void onClick(View v) {
71994be6100218126ce6a08bf1f56209578500b361fRoboErik            int id = v.getId();
72006991009e52024cbb3dde550988e06149e77a269Jae Seo            if (id == BUTTON_STOP_RES_ID || id == BUTTON_DISCONNECT_RES_ID) {
72194be6100218126ce6a08bf1f56209578500b361fRoboErik                if (mRoute.isSelected()) {
72206991009e52024cbb3dde550988e06149e77a269Jae Seo                    mRouter.unselect(id == BUTTON_STOP_RES_ID ?
72394be6100218126ce6a08bf1f56209578500b361fRoboErik                            MediaRouter.UNSELECT_REASON_STOPPED :
72494be6100218126ce6a08bf1f56209578500b361fRoboErik                            MediaRouter.UNSELECT_REASON_DISCONNECTED);
72594be6100218126ce6a08bf1f56209578500b361fRoboErik                }
72694be6100218126ce6a08bf1f56209578500b361fRoboErik                dismiss();
7277ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim            } else if (id == R.id.mr_control_play_pause) {
72894be6100218126ce6a08bf1f56209578500b361fRoboErik                if (mMediaController != null && mState != null) {
729ee7ae661b02471fe598566b1e90adbacda240b0bJae Seo                    boolean isPlaying = mState.getState() == PlaybackStateCompat.STATE_PLAYING;
730ee7ae661b02471fe598566b1e90adbacda240b0bJae Seo                    if (isPlaying) {
73194be6100218126ce6a08bf1f56209578500b361fRoboErik                        mMediaController.getTransportControls().pause();
73294be6100218126ce6a08bf1f56209578500b361fRoboErik                    } else {
73394be6100218126ce6a08bf1f56209578500b361fRoboErik                        mMediaController.getTransportControls().play();
73494be6100218126ce6a08bf1f56209578500b361fRoboErik                    }
735ee7ae661b02471fe598566b1e90adbacda240b0bJae Seo                    // Announce the action for accessibility.
736ee7ae661b02471fe598566b1e90adbacda240b0bJae Seo                    if (mAccessibilityManager != null && mAccessibilityManager.isEnabled()) {
737ee7ae661b02471fe598566b1e90adbacda240b0bJae Seo                        AccessibilityEvent event = AccessibilityEvent.obtain(
738ee7ae661b02471fe598566b1e90adbacda240b0bJae Seo                                AccessibilityEventCompat.TYPE_ANNOUNCEMENT);
739ee7ae661b02471fe598566b1e90adbacda240b0bJae Seo                        event.setPackageName(getContext().getPackageName());
740ee7ae661b02471fe598566b1e90adbacda240b0bJae Seo                        event.setClassName(getClass().getName());
741ee7ae661b02471fe598566b1e90adbacda240b0bJae Seo                        int resId = isPlaying ?
742ee7ae661b02471fe598566b1e90adbacda240b0bJae Seo                                R.string.mr_controller_pause : R.string.mr_controller_play;
743ee7ae661b02471fe598566b1e90adbacda240b0bJae Seo                        event.getText().add(getContext().getString(resId));
744ee7ae661b02471fe598566b1e90adbacda240b0bJae Seo                        mAccessibilityManager.sendAccessibilityEvent(event);
745ee7ae661b02471fe598566b1e90adbacda240b0bJae Seo                    }
74694be6100218126ce6a08bf1f56209578500b361fRoboErik                }
7471ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim            } else if (id == R.id.mr_close) {
748b48ccf48b0281e69262fc643d0def898aede407bSungsoo Lim                dismiss();
74911417b1cfde8f1749905f2d735623af9214148afJeff Brown            }
75011417b1cfde8f1749905f2d735623af9214148afJeff Brown        }
75111417b1cfde8f1749905f2d735623af9214148afJeff Brown    }
752005482649154d0970693b3967241eb4d2cb22003Jaewan Kim
753435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim    private class VolumeChangeListener implements OnSeekBarChangeListener {
754435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim        private final Runnable mStopTrackingTouch = new Runnable() {
7556051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo            @Override
756435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim            public void run() {
757435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim                if (mVolumeSliderTouched) {
758435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim                    mVolumeSliderTouched = false;
759435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim                    updateVolumeControl();
7606051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo                }
7616051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo            }
762435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim        };
7636051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo
764435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim        @Override
765435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim        public void onStartTrackingTouch(SeekBar seekBar) {
766435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim            if (mVolumeSliderTouched) {
767435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim                mVolumeSlider.removeCallbacks(mStopTrackingTouch);
768435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim            } else {
769435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim                mVolumeSliderTouched = true;
7706051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo            }
771435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim        }
7726051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo
773435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim        @Override
774435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim        public void onStopTrackingTouch(SeekBar seekBar) {
775435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim            // Defer resetting mVolumeSliderTouched to allow the media route provider
776435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim            // a little time to settle into its new state and publish the final
777435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim            // volume update.
778435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim            mVolumeSlider.postDelayed(mStopTrackingTouch, VOLUME_UPDATE_DELAY_MILLIS);
779435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim        }
780435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim
781435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim        @Override
782435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim        public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
783435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim            if (fromUser) {
784435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim                int tag = (int) seekBar.getTag();
785435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim                if (tag == VOLUME_SLIDER_TAG_MASTER) {
786435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim                    mRoute.requestSetVolume(progress);
787435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim                } else if (tag - VOLUME_SLIDER_TAG_BASE >= 0
788435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim                        && tag - VOLUME_SLIDER_TAG_BASE < getGroup().getRouteCount()) {
789435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim                    getGroup().getRouteAt(tag - VOLUME_SLIDER_TAG_BASE).requestSetVolume(progress);
790435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim                }
7916051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo            }
792435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim        }
793435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim    }
794435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim
795435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim    private class VolumeGroupAdapter extends ArrayAdapter<MediaRouter.RouteInfo> {
796435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim        final static float DISABLED_ALPHA = .3f;
7976051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo
7986051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo        public VolumeGroupAdapter(Context context, List<MediaRouter.RouteInfo> objects) {
7996051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo            super(context, 0, objects);
8006051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo        }
8016051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo
8026051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo        @Override
8036051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo        public View getView(final int position, View convertView, ViewGroup parent) {
8046051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo            View v = convertView;
8056051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo            if (v == null) {
8066051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo                v = LayoutInflater.from(getContext()).inflate(
8072c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim                        R.layout.mr_controller_volume_item, parent, false);
8086051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo            }
80919d268075834665bf62567b224dcd3549c92d3c3Jae Seo
8106051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo            MediaRouter.RouteInfo route = getItem(position);
8116051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo            if (route != null) {
8120e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo                boolean isEnabled = route.isEnabled();
8130e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo
8147ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim                TextView routeName = (TextView) v.findViewById(R.id.mr_name);
8150e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo                routeName.setEnabled(isEnabled);
8160e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo                routeName.setText(route.getName());
8176051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo
818ea15dd5d0313d55452f552d8583eb230b2c9506fJaewan Kim                MediaRouteVolumeSlider volumeSlider =
819ea15dd5d0313d55452f552d8583eb230b2c9506fJaewan Kim                        (MediaRouteVolumeSlider) v.findViewById(R.id.mr_volume_slider);
820435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim                volumeSlider.setTag(VOLUME_SLIDER_TAG_BASE + position);
821ea15dd5d0313d55452f552d8583eb230b2c9506fJaewan Kim                volumeSlider.setShowThumb(isEnabled);
8220e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo                if (isEnabled) {
8237447b1958129579090ee279caac7d703dba2ad28Sungsoo Lim                    if (isVolumeControlAvailable(route)) {
8240e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo                        volumeSlider.setMax(route.getVolumeMax());
8250e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo                        volumeSlider.setProgress(route.getVolume());
826435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim                        volumeSlider.setOnSeekBarChangeListener(mVolumeChangeListener);
827ea15dd5d0313d55452f552d8583eb230b2c9506fJaewan Kim                        volumeSlider.setEnabled(true);
8280e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo                    } else {
8290e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo                        volumeSlider.setMax(100);
8300e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo                        volumeSlider.setProgress(100);
8310e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo                        volumeSlider.setEnabled(false);
8320e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo                    }
8330e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo                }
8340e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo
8350e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo                ImageView volumeItemIcon =
8367ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim                        (ImageView) v.findViewById(R.id.mr_volume_item_icon);
83777367b4a1871417198d0399d9ad074314c758567Jae Seo                volumeItemIcon.setAlpha(isEnabled ? 255 : (int) (255 * DISABLED_ALPHA));
8386051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo            }
8396051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo            return v;
8406051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo        }
8416051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo    }
8426051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo
843005482649154d0970693b3967241eb4d2cb22003Jaewan Kim    private class FetchArtTask extends AsyncTask<Void, Void, Bitmap> {
8448bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo        final Bitmap mIconBitmap;
8458bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo        final Uri mIconUri;
8468bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo        int mBackgroundColor;
8478bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo
8488bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo        FetchArtTask() {
8498bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo            mIconBitmap = mDescription == null ? null : mDescription.getIconBitmap();
8508bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo            mIconUri = mDescription == null ? null : mDescription.getIconUri();
8518bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo        }
8528bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo
8538bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo        @Override
8548bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo        protected void onPreExecute() {
8558bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo            if (mArtIconBitmap == mIconBitmap && mArtIconUri == mIconUri) {
8568bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo                // Already handled the current art.
8578bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo                cancel(true);
8588bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo            }
8598bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo        }
860005482649154d0970693b3967241eb4d2cb22003Jaewan Kim
861005482649154d0970693b3967241eb4d2cb22003Jaewan Kim        @Override
862005482649154d0970693b3967241eb4d2cb22003Jaewan Kim        protected Bitmap doInBackground(Void... arg) {
86313d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim            Bitmap art = null;
8648bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo            if (mIconBitmap != null) {
8658bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo                art = mIconBitmap;
8668bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo            } else if (mIconUri != null) {
8678bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo                String scheme = mIconUri.getScheme();
868005482649154d0970693b3967241eb4d2cb22003Jaewan Kim                if (!(ContentResolver.SCHEME_ANDROID_RESOURCE.equals(scheme)
869005482649154d0970693b3967241eb4d2cb22003Jaewan Kim                        || ContentResolver.SCHEME_CONTENT.equals(scheme)
870005482649154d0970693b3967241eb4d2cb22003Jaewan Kim                        || ContentResolver.SCHEME_FILE.equals(scheme))) {
871005482649154d0970693b3967241eb4d2cb22003Jaewan Kim                    Log.w(TAG, "Icon Uri should point to local resources.");
872005482649154d0970693b3967241eb4d2cb22003Jaewan Kim                    return null;
873005482649154d0970693b3967241eb4d2cb22003Jaewan Kim                }
874005482649154d0970693b3967241eb4d2cb22003Jaewan Kim                BufferedInputStream stream = null;
875005482649154d0970693b3967241eb4d2cb22003Jaewan Kim                try {
876005482649154d0970693b3967241eb4d2cb22003Jaewan Kim                    stream = new BufferedInputStream(
8778bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo                            getContext().getContentResolver().openInputStream(mIconUri));
878005482649154d0970693b3967241eb4d2cb22003Jaewan Kim
87913d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim                    // Query art size.
880005482649154d0970693b3967241eb4d2cb22003Jaewan Kim                    BitmapFactory.Options options = new BitmapFactory.Options();
881005482649154d0970693b3967241eb4d2cb22003Jaewan Kim                    options.inJustDecodeBounds = true;
882005482649154d0970693b3967241eb4d2cb22003Jaewan Kim                    BitmapFactory.decodeStream(stream, null, options);
88313d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim                    if (options.outWidth == 0 || options.outHeight == 0) {
88413d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim                        return null;
88513d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim                    }
88613d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim                    // Rewind the stream in order to restart art decoding.
887005482649154d0970693b3967241eb4d2cb22003Jaewan Kim                    try {
888005482649154d0970693b3967241eb4d2cb22003Jaewan Kim                        stream.reset();
889005482649154d0970693b3967241eb4d2cb22003Jaewan Kim                    } catch (IOException e) {
890005482649154d0970693b3967241eb4d2cb22003Jaewan Kim                        // Failed to rewind the stream, try to reopen it.
891005482649154d0970693b3967241eb4d2cb22003Jaewan Kim                        stream.close();
892005482649154d0970693b3967241eb4d2cb22003Jaewan Kim                        stream = new BufferedInputStream(getContext().getContentResolver()
8938bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo                                .openInputStream(mIconUri));
894005482649154d0970693b3967241eb4d2cb22003Jaewan Kim                    }
89513d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim                    // Calculate required size to decode the art and possibly resize it.
896005482649154d0970693b3967241eb4d2cb22003Jaewan Kim                    options.inJustDecodeBounds = false;
89713d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim                    int reqHeight = getDesiredArtHeight(options.outWidth, options.outHeight);
89813d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim                    int ratio = options.outHeight / reqHeight;
899005482649154d0970693b3967241eb4d2cb22003Jaewan Kim                    options.inSampleSize = Math.max(1, Integer.highestOneBit(ratio));
900005482649154d0970693b3967241eb4d2cb22003Jaewan Kim                    if (isCancelled()) {
901005482649154d0970693b3967241eb4d2cb22003Jaewan Kim                        return null;
902005482649154d0970693b3967241eb4d2cb22003Jaewan Kim                    }
90313d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim                    art = BitmapFactory.decodeStream(stream, null, options);
904005482649154d0970693b3967241eb4d2cb22003Jaewan Kim                } catch (IOException e){
9058bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo                    Log.w(TAG, "Unable to open: " + mIconUri, e);
906005482649154d0970693b3967241eb4d2cb22003Jaewan Kim                } finally {
907005482649154d0970693b3967241eb4d2cb22003Jaewan Kim                    if (stream != null) {
908005482649154d0970693b3967241eb4d2cb22003Jaewan Kim                        try {
909005482649154d0970693b3967241eb4d2cb22003Jaewan Kim                            stream.close();
910005482649154d0970693b3967241eb4d2cb22003Jaewan Kim                        } catch (IOException e) {
911005482649154d0970693b3967241eb4d2cb22003Jaewan Kim                        }
912005482649154d0970693b3967241eb4d2cb22003Jaewan Kim                    }
913005482649154d0970693b3967241eb4d2cb22003Jaewan Kim                }
914005482649154d0970693b3967241eb4d2cb22003Jaewan Kim            }
915145e93b13dd025b278665494e7be0c15b8df5986Jaewan Kim            if (art != null && art.getWidth() < art.getHeight()) {
916c4c371f91673a882177f16fa95723e7e69f54882Insun Kang                // Portrait art requires dominant color as background color.
917145e93b13dd025b278665494e7be0c15b8df5986Jaewan Kim                Palette palette = new Palette.Builder(art).maximumColorCount(1).generate();
918be6358a7c928a09f2c767524299f86a8aad84558Dongwon Kang                mBackgroundColor = palette.getSwatches().isEmpty()
919145e93b13dd025b278665494e7be0c15b8df5986Jaewan Kim                        ? 0 : palette.getSwatches().get(0).getRgb();
920005482649154d0970693b3967241eb4d2cb22003Jaewan Kim            }
92113d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim            return art;
922005482649154d0970693b3967241eb4d2cb22003Jaewan Kim        }
923005482649154d0970693b3967241eb4d2cb22003Jaewan Kim
924005482649154d0970693b3967241eb4d2cb22003Jaewan Kim        @Override
925005482649154d0970693b3967241eb4d2cb22003Jaewan Kim        protected void onCancelled() {
926005482649154d0970693b3967241eb4d2cb22003Jaewan Kim            mFetchArtTask = null;
927005482649154d0970693b3967241eb4d2cb22003Jaewan Kim        }
928005482649154d0970693b3967241eb4d2cb22003Jaewan Kim
929005482649154d0970693b3967241eb4d2cb22003Jaewan Kim        @Override
93013d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim        protected void onPostExecute(Bitmap art) {
931005482649154d0970693b3967241eb4d2cb22003Jaewan Kim            mFetchArtTask = null;
9328bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo            if (mArtIconBitmap != mIconBitmap || mArtIconUri != mIconUri) {
9338bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo                mArtIconBitmap = mIconBitmap;
9348bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo                mArtIconUri = mIconUri;
9358bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo
9368bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo                mArtView.setImageBitmap(art);
9378bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo                mArtView.setBackgroundColor(mBackgroundColor);
9382c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim                updateLayoutHeight();
9398bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo            }
940005482649154d0970693b3967241eb4d2cb22003Jaewan Kim        }
941005482649154d0970693b3967241eb4d2cb22003Jaewan Kim    }
9426051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo}
943