MediaRouteControllerDialog.java revision 86a802c8d09983d8725cccf59217e65d3e0c6373
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;
236e547065f21f1645b3e9d5b3a3fd9720be8aede8Jaewan Kimimport android.content.res.Configuration;
246e547065f21f1645b3e9d5b3a3fd9720be8aede8Jaewan Kimimport android.content.res.Resources;
256051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seoimport android.content.res.TypedArray;
26005482649154d0970693b3967241eb4d2cb22003Jaewan Kimimport android.graphics.Bitmap;
27005482649154d0970693b3967241eb4d2cb22003Jaewan Kimimport android.graphics.BitmapFactory;
2886a802c8d09983d8725cccf59217e65d3e0c6373Jae Seoimport android.graphics.Color;
2986a802c8d09983d8725cccf59217e65d3e0c6373Jae Seoimport android.graphics.PorterDuff;
3013d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kimimport android.graphics.drawable.BitmapDrawable;
312ef36d857302c5cd738c7c8bdec53d31feebebbaJeff Brownimport android.graphics.drawable.Drawable;
32005482649154d0970693b3967241eb4d2cb22003Jaewan Kimimport android.net.Uri;
33005482649154d0970693b3967241eb4d2cb22003Jaewan Kimimport android.os.AsyncTask;
34418c688351713e9349227262163eef752a8e7ce6Jae Seoimport android.os.Build;
3511417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.os.Bundle;
3694be6100218126ce6a08bf1f56209578500b361fRoboErikimport android.os.RemoteException;
3794be6100218126ce6a08bf1f56209578500b361fRoboErikimport android.support.v4.media.MediaDescriptionCompat;
3894be6100218126ce6a08bf1f56209578500b361fRoboErikimport android.support.v4.media.MediaMetadataCompat;
3994be6100218126ce6a08bf1f56209578500b361fRoboErikimport android.support.v4.media.session.MediaControllerCompat;
4094be6100218126ce6a08bf1f56209578500b361fRoboErikimport android.support.v4.media.session.MediaSessionCompat;
4194be6100218126ce6a08bf1f56209578500b361fRoboErikimport android.support.v4.media.session.PlaybackStateCompat;
42005482649154d0970693b3967241eb4d2cb22003Jaewan Kimimport android.support.v7.graphics.Palette;
4311417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.support.v7.media.MediaRouteSelector;
4411417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.support.v7.media.MediaRouter;
45418c688351713e9349227262163eef752a8e7ce6Jae Seoimport android.support.v7.media.SeekBarJellybean;
4611417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.support.v7.mediarouter.R;
4794be6100218126ce6a08bf1f56209578500b361fRoboErikimport android.text.TextUtils;
4813d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kimimport android.util.DisplayMetrics;
4994be6100218126ce6a08bf1f56209578500b361fRoboErikimport android.util.Log;
5011417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.view.KeyEvent;
516051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seoimport android.view.LayoutInflater;
5211417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.view.View;
536051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seoimport android.view.ViewGroup;
542b274bd3e06bd33c9b2a0851256afcda94d96395Dongwon Kangimport android.view.ViewTreeObserver;
556051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seoimport android.widget.ArrayAdapter;
5611417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.widget.Button;
5711417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.widget.FrameLayout;
5894be6100218126ce6a08bf1f56209578500b361fRoboErikimport android.widget.ImageButton;
5994be6100218126ce6a08bf1f56209578500b361fRoboErikimport android.widget.ImageView;
60f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shahimport android.widget.LinearLayout;
616051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seoimport android.widget.ListView;
627ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Limimport android.widget.RelativeLayout;
63f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shahimport android.widget.SeekBar;
6494be6100218126ce6a08bf1f56209578500b361fRoboErikimport android.widget.TextView;
6511417b1cfde8f1749905f2d735623af9214148afJeff Brown
66005482649154d0970693b3967241eb4d2cb22003Jaewan Kimimport java.io.BufferedInputStream;
67005482649154d0970693b3967241eb4d2cb22003Jaewan Kimimport java.io.IOException;
686051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seoimport java.util.List;
69005482649154d0970693b3967241eb4d2cb22003Jaewan Kim
7011417b1cfde8f1749905f2d735623af9214148afJeff Brown/**
7111417b1cfde8f1749905f2d735623af9214148afJeff Brown * This class implements the route controller dialog for {@link MediaRouter}.
7211417b1cfde8f1749905f2d735623af9214148afJeff Brown * <p>
7311417b1cfde8f1749905f2d735623af9214148afJeff Brown * This dialog allows the user to control or disconnect from the currently selected route.
7411417b1cfde8f1749905f2d735623af9214148afJeff Brown * </p>
7511417b1cfde8f1749905f2d735623af9214148afJeff Brown *
7611417b1cfde8f1749905f2d735623af9214148afJeff Brown * @see MediaRouteButton
7711417b1cfde8f1749905f2d735623af9214148afJeff Brown * @see MediaRouteActionProvider
7811417b1cfde8f1749905f2d735623af9214148afJeff Brown */
7989530d511efd566d53bedd9178454dd01d227c61Jae Seopublic class MediaRouteControllerDialog extends AlertDialog {
8011417b1cfde8f1749905f2d735623af9214148afJeff Brown    private static final String TAG = "MediaRouteControllerDialog";
8111417b1cfde8f1749905f2d735623af9214148afJeff Brown
82a4bcfe765789ebef71c36cbb2dba3f9f881fa5b4Jae Seo    // STOPSHIP: Remove the flag when the group volume control implementation completes.
83a4bcfe765789ebef71c36cbb2dba3f9f881fa5b4Jae Seo    private static final boolean USE_GROUP = false;
84a4bcfe765789ebef71c36cbb2dba3f9f881fa5b4Jae Seo
85f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah    // Time to wait before updating the volume when the user lets go of the seek bar
86f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah    // to allow the route provider time to propagate the change and publish a new
87f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah    // route descriptor.
88f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah    private static final int VOLUME_UPDATE_DELAY_MILLIS = 250;
89f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah
9011417b1cfde8f1749905f2d735623af9214148afJeff Brown    private final MediaRouter mRouter;
9111417b1cfde8f1749905f2d735623af9214148afJeff Brown    private final MediaRouterCallback mCallback;
9211417b1cfde8f1749905f2d735623af9214148afJeff Brown    private final MediaRouter.RouteInfo mRoute;
9311417b1cfde8f1749905f2d735623af9214148afJeff Brown
94eff7719415542ba819054863b0995f07742a7a8aJeff Brown    private boolean mCreated;
95e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik    private boolean mAttachedToWindow;
96e2148398ae5d03c22789aebc3d6359b5ff86c077Jae Seo
976e547065f21f1645b3e9d5b3a3fd9720be8aede8Jaewan Kim    private int mOrientation;
986e547065f21f1645b3e9d5b3a3fd9720be8aede8Jaewan Kim    private int mDialogWidthPortrait;
996e547065f21f1645b3e9d5b3a3fd9720be8aede8Jaewan Kim    private int mDialogWidthLandscape;
1004ec1a0371ebb43ba1537354becb9241c105d2fb8Jaewan Kim    private int mDialogPaddingHorizontal;
10111417b1cfde8f1749905f2d735623af9214148afJeff Brown
1027ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim    private View mCustomControlView;
10311417b1cfde8f1749905f2d735623af9214148afJeff Brown
10411417b1cfde8f1749905f2d735623af9214148afJeff Brown    private Button mDisconnectButton;
10594be6100218126ce6a08bf1f56209578500b361fRoboErik    private Button mStopCastingButton;
1061ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim    private ImageButton mPlayPauseButton;
107b48ccf48b0281e69262fc643d0def898aede407bSungsoo Lim    private ImageButton mCloseButton;
1081ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim    private ImageButton mGroupExpandCollapseButton;
10994be6100218126ce6a08bf1f56209578500b361fRoboErik
1101ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim    private FrameLayout mCustomControlLayout;
1112b274bd3e06bd33c9b2a0851256afcda94d96395Dongwon Kang    private FrameLayout mDefaultControlLayout;
1122b274bd3e06bd33c9b2a0851256afcda94d96395Dongwon Kang    private boolean mNeedToAdjustControlFrameLayout = true;
11394be6100218126ce6a08bf1f56209578500b361fRoboErik    private ImageView mArtView;
1141ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim    private TextView mTitleView;
1151ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim    private TextView mSubtitleView;
1167ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim    private TextView mRouteNameTextView;
11794be6100218126ce6a08bf1f56209578500b361fRoboErik
118f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah    private boolean mVolumeControlEnabled = true;
1191ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim    private LinearLayout mControlLayout;
1201ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim    private RelativeLayout mPlaybackControl;
1211ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim    private LinearLayout mVolumeControl;
1221ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim    private View mDividerView;
1231ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim
1246051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo    private ListView mVolumeGroupList;
1251ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim    private SeekBar mVolumeSlider;
1261ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim    private boolean mVolumeSliderTouched;
12786a802c8d09983d8725cccf59217e65d3e0c6373Jae Seo    private int mVolumeSliderColor;
128f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah
12994be6100218126ce6a08bf1f56209578500b361fRoboErik    private MediaControllerCompat mMediaController;
13094be6100218126ce6a08bf1f56209578500b361fRoboErik    private MediaControllerCallback mControllerCallback;
13194be6100218126ce6a08bf1f56209578500b361fRoboErik    private PlaybackStateCompat mState;
13294be6100218126ce6a08bf1f56209578500b361fRoboErik    private MediaDescriptionCompat mDescription;
13394be6100218126ce6a08bf1f56209578500b361fRoboErik
134005482649154d0970693b3967241eb4d2cb22003Jaewan Kim    private FetchArtTask mFetchArtTask;
1352b274bd3e06bd33c9b2a0851256afcda94d96395Dongwon Kang    private boolean mIsGroupExpanded;
13611417b1cfde8f1749905f2d735623af9214148afJeff Brown
13711417b1cfde8f1749905f2d735623af9214148afJeff Brown    public MediaRouteControllerDialog(Context context) {
13811417b1cfde8f1749905f2d735623af9214148afJeff Brown        this(context, 0);
13911417b1cfde8f1749905f2d735623af9214148afJeff Brown    }
14011417b1cfde8f1749905f2d735623af9214148afJeff Brown
14111417b1cfde8f1749905f2d735623af9214148afJeff Brown    public MediaRouteControllerDialog(Context context, int theme) {
14294be6100218126ce6a08bf1f56209578500b361fRoboErik        super(MediaRouterThemeHelper.createThemedContext(context), theme);
14311417b1cfde8f1749905f2d735623af9214148afJeff Brown        context = getContext();
14411417b1cfde8f1749905f2d735623af9214148afJeff Brown
14594be6100218126ce6a08bf1f56209578500b361fRoboErik        mControllerCallback = new MediaControllerCallback();
14611417b1cfde8f1749905f2d735623af9214148afJeff Brown        mRouter = MediaRouter.getInstance(context);
14711417b1cfde8f1749905f2d735623af9214148afJeff Brown        mCallback = new MediaRouterCallback();
14811417b1cfde8f1749905f2d735623af9214148afJeff Brown        mRoute = mRouter.getSelectedRoute();
149e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik        setMediaSession(mRouter.getMediaSessionToken());
15011417b1cfde8f1749905f2d735623af9214148afJeff Brown    }
15111417b1cfde8f1749905f2d735623af9214148afJeff Brown
15211417b1cfde8f1749905f2d735623af9214148afJeff Brown    /**
15311417b1cfde8f1749905f2d735623af9214148afJeff Brown     * Gets the route that this dialog is controlling.
15411417b1cfde8f1749905f2d735623af9214148afJeff Brown     */
15511417b1cfde8f1749905f2d735623af9214148afJeff Brown    public MediaRouter.RouteInfo getRoute() {
15611417b1cfde8f1749905f2d735623af9214148afJeff Brown        return mRoute;
15711417b1cfde8f1749905f2d735623af9214148afJeff Brown    }
15811417b1cfde8f1749905f2d735623af9214148afJeff Brown
1596051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo    private MediaRouter.RouteGroup getGroup() {
1606051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo        if (mRoute instanceof MediaRouter.RouteGroup) {
1616051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo            return (MediaRouter.RouteGroup) mRoute;
1626051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo        }
1636051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo        return null;
1646051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo    }
1656051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo
16611417b1cfde8f1749905f2d735623af9214148afJeff Brown    /**
16711417b1cfde8f1749905f2d735623af9214148afJeff Brown     * Provides the subclass an opportunity to create a view that will
16811417b1cfde8f1749905f2d735623af9214148afJeff Brown     * be included within the body of the dialog to offer additional media controls
16911417b1cfde8f1749905f2d735623af9214148afJeff Brown     * for the currently playing content.
17011417b1cfde8f1749905f2d735623af9214148afJeff Brown     *
17111417b1cfde8f1749905f2d735623af9214148afJeff Brown     * @param savedInstanceState The dialog's saved instance state.
17211417b1cfde8f1749905f2d735623af9214148afJeff Brown     * @return The media control view, or null if none.
17311417b1cfde8f1749905f2d735623af9214148afJeff Brown     */
17411417b1cfde8f1749905f2d735623af9214148afJeff Brown    public View onCreateMediaControlView(Bundle savedInstanceState) {
17511417b1cfde8f1749905f2d735623af9214148afJeff Brown        return null;
17611417b1cfde8f1749905f2d735623af9214148afJeff Brown    }
17711417b1cfde8f1749905f2d735623af9214148afJeff Brown
17811417b1cfde8f1749905f2d735623af9214148afJeff Brown    /**
17911417b1cfde8f1749905f2d735623af9214148afJeff Brown     * Gets the media control view that was created by {@link #onCreateMediaControlView(Bundle)}.
18011417b1cfde8f1749905f2d735623af9214148afJeff Brown     *
18111417b1cfde8f1749905f2d735623af9214148afJeff Brown     * @return The media control view, or null if none.
18211417b1cfde8f1749905f2d735623af9214148afJeff Brown     */
18311417b1cfde8f1749905f2d735623af9214148afJeff Brown    public View getMediaControlView() {
1847ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim        return mCustomControlView;
18511417b1cfde8f1749905f2d735623af9214148afJeff Brown    }
18611417b1cfde8f1749905f2d735623af9214148afJeff Brown
187eff7719415542ba819054863b0995f07742a7a8aJeff Brown    /**
188f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah     * Sets whether to enable the volume slider and volume control using the volume keys
189f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah     * when the route supports it.
190f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah     * <p>
191f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah     * The default value is true.
192f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah     * </p>
193f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah     */
194f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah    public void setVolumeControlEnabled(boolean enable) {
195f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah        if (mVolumeControlEnabled != enable) {
196f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah            mVolumeControlEnabled = enable;
197f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah            if (mCreated) {
1981ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                updateVolumeControl();
199f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah            }
200f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah        }
201f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah    }
202f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah
203f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah    /**
204f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah     * Returns whether to enable the volume slider and volume control using the volume keys
205f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah     * when the route supports it.
206f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah     */
207f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah    public boolean isVolumeControlEnabled() {
208f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah        return mVolumeControlEnabled;
209f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah    }
210f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah
211f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah    /**
21294be6100218126ce6a08bf1f56209578500b361fRoboErik     * Set the session to use for metadata and transport controls. The dialog
21394be6100218126ce6a08bf1f56209578500b361fRoboErik     * will listen to changes on this session and update the UI automatically in
21494be6100218126ce6a08bf1f56209578500b361fRoboErik     * response to changes.
21594be6100218126ce6a08bf1f56209578500b361fRoboErik     *
21694be6100218126ce6a08bf1f56209578500b361fRoboErik     * @param sessionToken The token for the session to use.
217eff7719415542ba819054863b0995f07742a7a8aJeff Brown     */
218e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik    private void setMediaSession(MediaSessionCompat.Token sessionToken) {
21994be6100218126ce6a08bf1f56209578500b361fRoboErik        if (mMediaController != null) {
22094be6100218126ce6a08bf1f56209578500b361fRoboErik            mMediaController.unregisterCallback(mControllerCallback);
22194be6100218126ce6a08bf1f56209578500b361fRoboErik            mMediaController = null;
22294be6100218126ce6a08bf1f56209578500b361fRoboErik        }
22394be6100218126ce6a08bf1f56209578500b361fRoboErik        if (sessionToken == null) {
22494be6100218126ce6a08bf1f56209578500b361fRoboErik            return;
22594be6100218126ce6a08bf1f56209578500b361fRoboErik        }
226e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik        if (!mAttachedToWindow) {
227e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik            return;
228e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik        }
22994be6100218126ce6a08bf1f56209578500b361fRoboErik        try {
23094be6100218126ce6a08bf1f56209578500b361fRoboErik            mMediaController = new MediaControllerCompat(getContext(), sessionToken);
23194be6100218126ce6a08bf1f56209578500b361fRoboErik        } catch (RemoteException e) {
23294be6100218126ce6a08bf1f56209578500b361fRoboErik            Log.e(TAG, "Error creating media controller in setMediaSession.", e);
23394be6100218126ce6a08bf1f56209578500b361fRoboErik        }
23494be6100218126ce6a08bf1f56209578500b361fRoboErik        if (mMediaController != null) {
23594be6100218126ce6a08bf1f56209578500b361fRoboErik            mMediaController.registerCallback(mControllerCallback);
236eff7719415542ba819054863b0995f07742a7a8aJeff Brown        }
23794be6100218126ce6a08bf1f56209578500b361fRoboErik        MediaMetadataCompat metadata = mMediaController == null ? null
23894be6100218126ce6a08bf1f56209578500b361fRoboErik                : mMediaController.getMetadata();
23994be6100218126ce6a08bf1f56209578500b361fRoboErik        mDescription = metadata == null ? null : metadata.getDescription();
24094be6100218126ce6a08bf1f56209578500b361fRoboErik        mState = mMediaController == null ? null : mMediaController.getPlaybackState();
24194be6100218126ce6a08bf1f56209578500b361fRoboErik        update();
242eff7719415542ba819054863b0995f07742a7a8aJeff Brown    }
243eff7719415542ba819054863b0995f07742a7a8aJeff Brown
244eff7719415542ba819054863b0995f07742a7a8aJeff Brown    /**
24594be6100218126ce6a08bf1f56209578500b361fRoboErik     * Gets the description being used by the default UI.
24694be6100218126ce6a08bf1f56209578500b361fRoboErik     *
24794be6100218126ce6a08bf1f56209578500b361fRoboErik     * @return The current description.
248eff7719415542ba819054863b0995f07742a7a8aJeff Brown     */
24994be6100218126ce6a08bf1f56209578500b361fRoboErik    public MediaSessionCompat.Token getMediaSession() {
25094be6100218126ce6a08bf1f56209578500b361fRoboErik        return mMediaController == null ? null : mMediaController.getSessionToken();
251eff7719415542ba819054863b0995f07742a7a8aJeff Brown    }
252eff7719415542ba819054863b0995f07742a7a8aJeff Brown
25311417b1cfde8f1749905f2d735623af9214148afJeff Brown    @Override
25411417b1cfde8f1749905f2d735623af9214148afJeff Brown    protected void onCreate(Bundle savedInstanceState) {
25511417b1cfde8f1749905f2d735623af9214148afJeff Brown        super.onCreate(savedInstanceState);
25611417b1cfde8f1749905f2d735623af9214148afJeff Brown
257a09c7b30d3a5c53281db955eabce171e1aec6feaSungsoo Lim        setContentView(R.layout.mr_controller_material_dialog_b);
2586e547065f21f1645b3e9d5b3a3fd9720be8aede8Jaewan Kim        Resources res = getContext().getResources();
259e2148398ae5d03c22789aebc3d6359b5ff86c077Jae Seo        mDialogWidthPortrait = res.getDimensionPixelSize(R.dimen.mr_dialog_content_width_portrait);
2606e547065f21f1645b3e9d5b3a3fd9720be8aede8Jaewan Kim        mDialogWidthLandscape = res.getDimensionPixelSize(
261e2148398ae5d03c22789aebc3d6359b5ff86c077Jae Seo                R.dimen.mr_dialog_content_width_landscape);
26211417b1cfde8f1749905f2d735623af9214148afJeff Brown
26394be6100218126ce6a08bf1f56209578500b361fRoboErik        ClickListener listener = new ClickListener();
264d6748a7926ebb2450337f9f0ff4d445c980344e5Jeff Brown
2651ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim        mDisconnectButton = (Button) findViewById(R.id.mr_button_disconnect);
26694be6100218126ce6a08bf1f56209578500b361fRoboErik        mDisconnectButton.setOnClickListener(listener);
26711417b1cfde8f1749905f2d735623af9214148afJeff Brown
2681ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim        mStopCastingButton = (Button) findViewById(R.id.mr_button_stop);
26994be6100218126ce6a08bf1f56209578500b361fRoboErik        mStopCastingButton.setOnClickListener(listener);
27011417b1cfde8f1749905f2d735623af9214148afJeff Brown
2711ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim        mRouteNameTextView = (TextView) findViewById(R.id.mr_name);
2721ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim        mCloseButton = (ImageButton) findViewById(R.id.mr_close);
273b48ccf48b0281e69262fc643d0def898aede407bSungsoo Lim        mCloseButton.setOnClickListener(listener);
2741ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim        mCustomControlLayout = (FrameLayout) findViewById(R.id.mr_custom_control);
2752b274bd3e06bd33c9b2a0851256afcda94d96395Dongwon Kang        mDefaultControlLayout = (FrameLayout) findViewById(R.id.mr_default_control);
2762b274bd3e06bd33c9b2a0851256afcda94d96395Dongwon Kang        ViewTreeObserver observer = mDefaultControlLayout.getViewTreeObserver();
2772b274bd3e06bd33c9b2a0851256afcda94d96395Dongwon Kang        observer.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
2782b274bd3e06bd33c9b2a0851256afcda94d96395Dongwon Kang            @Override
2792b274bd3e06bd33c9b2a0851256afcda94d96395Dongwon Kang            public void onGlobalLayout() {
2802b274bd3e06bd33c9b2a0851256afcda94d96395Dongwon Kang                updateControlFrameLayout();
2812b274bd3e06bd33c9b2a0851256afcda94d96395Dongwon Kang            }
2822b274bd3e06bd33c9b2a0851256afcda94d96395Dongwon Kang        });
2837ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim        mArtView = (ImageView) findViewById(R.id.mr_art);
2846051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo
2851ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim        mControlLayout = (LinearLayout) findViewById(R.id.mr_control);
2861ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim        mDividerView = findViewById(R.id.mr_control_divider);
2871ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim
2881ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim        mPlaybackControl = (RelativeLayout) findViewById(R.id.mr_playback_control);
2891ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim        mTitleView = (TextView) findViewById(R.id.mr_control_title);
2901ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim        mSubtitleView = (TextView) findViewById(R.id.mr_control_subtitle);
2911ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim        mPlayPauseButton = (ImageButton) findViewById(R.id.mr_control_play_pause);
2921ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim        mPlayPauseButton.setOnClickListener(listener);
2931ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim
2941ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim        mVolumeControl = (LinearLayout) findViewById(R.id.mr_volume_control);
2951ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim        mVolumeSlider = (SeekBar) findViewById(R.id.mr_volume_slider);
2961ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim        mVolumeSlider.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
2971ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim            private final Runnable mStopTrackingTouch = new Runnable() {
2981ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                @Override
2991ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                public void run() {
3001ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                    if (mVolumeSliderTouched) {
3011ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                        mVolumeSliderTouched = false;
3021ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                        updateVolumeControl();
3031ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                    }
3041ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                }
3051ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim            };
3061ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim
3071ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim            @Override
3081ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim            public void onStartTrackingTouch(SeekBar seekBar) {
3091ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                if (mVolumeSliderTouched) {
3101ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                    mVolumeSlider.removeCallbacks(mStopTrackingTouch);
3111ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                } else {
3121ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                    mVolumeSliderTouched = true;
3131ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                }
3141ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim            }
3151ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim
3161ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim            @Override
3171ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim            public void onStopTrackingTouch(SeekBar seekBar) {
3181ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                // Defer resetting mVolumeSliderTouched to allow the media route provider
3191ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                // a little time to settle into its new state and publish the final
3201ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                // volume update.
3211ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                mVolumeSlider.postDelayed(mStopTrackingTouch, VOLUME_UPDATE_DELAY_MILLIS);
3221ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim            }
3231ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim
3241ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim            @Override
3251ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
3261ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                if (fromUser) {
3271ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                    mRoute.requestSetVolume(progress);
3281ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                }
3291ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim            }
3301ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim        });
33186a802c8d09983d8725cccf59217e65d3e0c6373Jae Seo        mVolumeSliderColor = MediaRouterThemeHelper.getVolumeSliderColor(getContext());
33286a802c8d09983d8725cccf59217e65d3e0c6373Jae Seo        setVolumeSliderColor(mVolumeSlider, mVolumeSliderColor);
3331ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim
3341ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim        TypedArray styledAttributes = getContext().obtainStyledAttributes(new int[] {
3351ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                R.attr.mediaRouteExpandGroupDrawable,
3361ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                R.attr.mediaRouteCollapseGroupDrawable
3371ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim        });
3381ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim        final Drawable expandGroupDrawable = styledAttributes.getDrawable(0);
3391ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim        final Drawable collapseGroupDrawable = styledAttributes.getDrawable(1);
3401ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim        styledAttributes.recycle();
3411ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim
3427ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim        mVolumeGroupList = (ListView)findViewById(R.id.mr_volume_group_list);
3431ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim        mGroupExpandCollapseButton = (ImageButton) findViewById(R.id.mr_group_expand_collapse);
3441ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim        mGroupExpandCollapseButton.setOnClickListener(new View.OnClickListener() {
3451ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim            @Override
3461ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim            public void onClick(View v) {
3472b274bd3e06bd33c9b2a0851256afcda94d96395Dongwon Kang                mIsGroupExpanded = !mIsGroupExpanded;
3482b274bd3e06bd33c9b2a0851256afcda94d96395Dongwon Kang                if (mIsGroupExpanded) {
3491ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                    mGroupExpandCollapseButton.setImageDrawable(collapseGroupDrawable);
3501ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                    mVolumeGroupList.setVisibility(View.VISIBLE);
3511ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                    mVolumeGroupList.setAdapter(
3521ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                            new VolumeGroupAdapter(getContext(), getGroup().getRoutes()));
3531ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                } else {
3541ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                    mGroupExpandCollapseButton.setImageDrawable(expandGroupDrawable);
3551ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                    mVolumeGroupList.setVisibility(View.GONE);
3561ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                }
3572b274bd3e06bd33c9b2a0851256afcda94d96395Dongwon Kang                mNeedToAdjustControlFrameLayout = true;
3581ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim            }
3591ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim        });
36011417b1cfde8f1749905f2d735623af9214148afJeff Brown
3617ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim        mCustomControlView = onCreateMediaControlView(savedInstanceState);
3627ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim        if (mCustomControlView != null) {
3631ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim            mCustomControlLayout.addView(mCustomControlView);
3641ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim            mCustomControlLayout.setVisibility(View.VISIBLE);
3657ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim            mArtView.setVisibility(View.GONE);
36611417b1cfde8f1749905f2d735623af9214148afJeff Brown        }
36786a802c8d09983d8725cccf59217e65d3e0c6373Jae Seo
36886a802c8d09983d8725cccf59217e65d3e0c6373Jae Seo        mCreated = true;
3697ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim        update();
37011417b1cfde8f1749905f2d735623af9214148afJeff Brown    }
37111417b1cfde8f1749905f2d735623af9214148afJeff Brown
3726e547065f21f1645b3e9d5b3a3fd9720be8aede8Jaewan Kim    /**
3736e547065f21f1645b3e9d5b3a3fd9720be8aede8Jaewan Kim     * Called by {@link MediaRouteControllerDialogFragment} when the device configuration
3746e547065f21f1645b3e9d5b3a3fd9720be8aede8Jaewan Kim     * is changed.
3756e547065f21f1645b3e9d5b3a3fd9720be8aede8Jaewan Kim     */
3766e547065f21f1645b3e9d5b3a3fd9720be8aede8Jaewan Kim    void onConfigurationChanged(Configuration newConfig) {
3776e547065f21f1645b3e9d5b3a3fd9720be8aede8Jaewan Kim        onOrientationChanged(newConfig.orientation);
3786e547065f21f1645b3e9d5b3a3fd9720be8aede8Jaewan Kim    }
3796e547065f21f1645b3e9d5b3a3fd9720be8aede8Jaewan Kim
3806e547065f21f1645b3e9d5b3a3fd9720be8aede8Jaewan Kim    private void onOrientationChanged(int orientation) {
3816e547065f21f1645b3e9d5b3a3fd9720be8aede8Jaewan Kim        if (!mAttachedToWindow || mOrientation == orientation) {
3826e547065f21f1645b3e9d5b3a3fd9720be8aede8Jaewan Kim            return;
3836e547065f21f1645b3e9d5b3a3fd9720be8aede8Jaewan Kim        }
3846e547065f21f1645b3e9d5b3a3fd9720be8aede8Jaewan Kim        mOrientation = orientation;
385b7b02f5cac8b760805d98ddbfe03e0730bee6709Sungsoo Lim        int dialogWidth = mOrientation == Configuration.ORIENTATION_LANDSCAPE
386b7b02f5cac8b760805d98ddbfe03e0730bee6709Sungsoo Lim                ? mDialogWidthLandscape : mDialogWidthPortrait;
387b7b02f5cac8b760805d98ddbfe03e0730bee6709Sungsoo Lim        getWindow().setLayout(dialogWidth, ViewGroup.LayoutParams.WRAP_CONTENT);
388b7b02f5cac8b760805d98ddbfe03e0730bee6709Sungsoo Lim
389e2148398ae5d03c22789aebc3d6359b5ff86c077Jae Seo        View decorView = getWindow().getDecorView();
390e2148398ae5d03c22789aebc3d6359b5ff86c077Jae Seo        mDialogPaddingHorizontal = decorView.getPaddingLeft() + decorView.getPaddingRight();
391e2148398ae5d03c22789aebc3d6359b5ff86c077Jae Seo
392b7b02f5cac8b760805d98ddbfe03e0730bee6709Sungsoo Lim        // Manually set the width of buttons to workaround unexpected text alignment changes.
393e2148398ae5d03c22789aebc3d6359b5ff86c077Jae Seo        int buttonWidth = (dialogWidth - mDialogPaddingHorizontal) / 2;
394e2148398ae5d03c22789aebc3d6359b5ff86c077Jae Seo
395b7b02f5cac8b760805d98ddbfe03e0730bee6709Sungsoo Lim        ViewGroup.LayoutParams lp = mStopCastingButton.getLayoutParams();
396b7b02f5cac8b760805d98ddbfe03e0730bee6709Sungsoo Lim        lp.width = buttonWidth;
397b7b02f5cac8b760805d98ddbfe03e0730bee6709Sungsoo Lim        mStopCastingButton.setLayoutParams(lp);
398b7b02f5cac8b760805d98ddbfe03e0730bee6709Sungsoo Lim
399b7b02f5cac8b760805d98ddbfe03e0730bee6709Sungsoo Lim        lp = mDisconnectButton.getLayoutParams();
400b7b02f5cac8b760805d98ddbfe03e0730bee6709Sungsoo Lim        lp.width = buttonWidth;
401b7b02f5cac8b760805d98ddbfe03e0730bee6709Sungsoo Lim        mDisconnectButton.setLayoutParams(lp);
402b7b02f5cac8b760805d98ddbfe03e0730bee6709Sungsoo Lim
40313d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim        updateArtView();
4046e547065f21f1645b3e9d5b3a3fd9720be8aede8Jaewan Kim    }
4056e547065f21f1645b3e9d5b3a3fd9720be8aede8Jaewan Kim
40611417b1cfde8f1749905f2d735623af9214148afJeff Brown    @Override
40711417b1cfde8f1749905f2d735623af9214148afJeff Brown    public void onAttachedToWindow() {
40811417b1cfde8f1749905f2d735623af9214148afJeff Brown        super.onAttachedToWindow();
409e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik        mAttachedToWindow = true;
41011417b1cfde8f1749905f2d735623af9214148afJeff Brown
41111417b1cfde8f1749905f2d735623af9214148afJeff Brown        mRouter.addCallback(MediaRouteSelector.EMPTY, mCallback,
41211417b1cfde8f1749905f2d735623af9214148afJeff Brown                MediaRouter.CALLBACK_FLAG_UNFILTERED_EVENTS);
413e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik        setMediaSession(mRouter.getMediaSessionToken());
4146e547065f21f1645b3e9d5b3a3fd9720be8aede8Jaewan Kim        onOrientationChanged(getContext().getResources().getConfiguration().orientation);
41511417b1cfde8f1749905f2d735623af9214148afJeff Brown    }
41611417b1cfde8f1749905f2d735623af9214148afJeff Brown
41711417b1cfde8f1749905f2d735623af9214148afJeff Brown    @Override
41811417b1cfde8f1749905f2d735623af9214148afJeff Brown    public void onDetachedFromWindow() {
41911417b1cfde8f1749905f2d735623af9214148afJeff Brown        mRouter.removeCallback(mCallback);
420e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik        setMediaSession(null);
421e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik        mAttachedToWindow = false;
42211417b1cfde8f1749905f2d735623af9214148afJeff Brown        super.onDetachedFromWindow();
42311417b1cfde8f1749905f2d735623af9214148afJeff Brown    }
42411417b1cfde8f1749905f2d735623af9214148afJeff Brown
42511417b1cfde8f1749905f2d735623af9214148afJeff Brown    @Override
42611417b1cfde8f1749905f2d735623af9214148afJeff Brown    public boolean onKeyDown(int keyCode, KeyEvent event) {
427ce8cbd614a64f94e54b936d66ecd14b6c1282ddfJeff Brown        if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN
428ce8cbd614a64f94e54b936d66ecd14b6c1282ddfJeff Brown                || keyCode == KeyEvent.KEYCODE_VOLUME_UP) {
429ce8cbd614a64f94e54b936d66ecd14b6c1282ddfJeff Brown            mRoute.requestUpdateVolume(keyCode == KeyEvent.KEYCODE_VOLUME_DOWN ? -1 : 1);
430ce8cbd614a64f94e54b936d66ecd14b6c1282ddfJeff Brown            return true;
43111417b1cfde8f1749905f2d735623af9214148afJeff Brown        }
43211417b1cfde8f1749905f2d735623af9214148afJeff Brown        return super.onKeyDown(keyCode, event);
43311417b1cfde8f1749905f2d735623af9214148afJeff Brown    }
43411417b1cfde8f1749905f2d735623af9214148afJeff Brown
43511417b1cfde8f1749905f2d735623af9214148afJeff Brown    @Override
43611417b1cfde8f1749905f2d735623af9214148afJeff Brown    public boolean onKeyUp(int keyCode, KeyEvent event) {
437ce8cbd614a64f94e54b936d66ecd14b6c1282ddfJeff Brown        if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN
438ce8cbd614a64f94e54b936d66ecd14b6c1282ddfJeff Brown                || keyCode == KeyEvent.KEYCODE_VOLUME_UP) {
439ce8cbd614a64f94e54b936d66ecd14b6c1282ddfJeff Brown            return true;
44011417b1cfde8f1749905f2d735623af9214148afJeff Brown        }
44111417b1cfde8f1749905f2d735623af9214148afJeff Brown        return super.onKeyUp(keyCode, event);
44211417b1cfde8f1749905f2d735623af9214148afJeff Brown    }
44311417b1cfde8f1749905f2d735623af9214148afJeff Brown
4447ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim    private void update() {
44511417b1cfde8f1749905f2d735623af9214148afJeff Brown        if (!mRoute.isSelected() || mRoute.isDefault()) {
44611417b1cfde8f1749905f2d735623af9214148afJeff Brown            dismiss();
4477ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim            return;
44811417b1cfde8f1749905f2d735623af9214148afJeff Brown        }
44994be6100218126ce6a08bf1f56209578500b361fRoboErik        if (!mCreated) {
4507ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim            return;
45194be6100218126ce6a08bf1f56209578500b361fRoboErik        }
4522ef36d857302c5cd738c7c8bdec53d31feebebbaJeff Brown
4537ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim        mRouteNameTextView.setText(mRoute.getName());
4545c6a5799fca3b622ad82ac77d8dfbed7dfd4ec7fSungsoo Lim        mDisconnectButton.setVisibility(mRoute.canDisconnect() ? View.VISIBLE : View.INVISIBLE);
45594be6100218126ce6a08bf1f56209578500b361fRoboErik
4567ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim        if (mCustomControlView == null) {
457005482649154d0970693b3967241eb4d2cb22003Jaewan Kim            if (mFetchArtTask != null) {
458005482649154d0970693b3967241eb4d2cb22003Jaewan Kim                mFetchArtTask.cancel(true);
45966937fc7dfe22c8c505bf735781d1f5b62f08e34Dongwon Kang            }
460005482649154d0970693b3967241eb4d2cb22003Jaewan Kim            mFetchArtTask = new FetchArtTask();
461005482649154d0970693b3967241eb4d2cb22003Jaewan Kim            mFetchArtTask.execute();
462f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah        }
4631ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim        updateVolumeControl();
4641ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim        updatePlaybackControl();
4651ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim    }
4661ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim
4671ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim    private void updateVolumeControl() {
4681ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim        if (!mVolumeSliderTouched) {
4691ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim            if (isVolumeControlAvailable()) {
4701ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                mVolumeControl.setVisibility(View.VISIBLE);
4711ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                mVolumeSlider.setMax(mRoute.getVolumeMax());
4721ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                mVolumeSlider.setProgress(mRoute.getVolume());
4731ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                if (USE_GROUP) {
4741ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                    if (getGroup() == null) {
4751ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                        mGroupExpandCollapseButton.setVisibility(View.GONE);
4761ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                    } else {
4771ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                        mGroupExpandCollapseButton.setVisibility(View.VISIBLE);
4781ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                        VolumeGroupAdapter adapter =
4791ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                                (VolumeGroupAdapter) mVolumeGroupList.getAdapter();
4801ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                        if (adapter != null) {
4811ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                            adapter.notifyDataSetChanged();
4821ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                        }
4831ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                    }
4841ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                }
4851ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim            } else {
4861ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                mVolumeControl.setVisibility(View.GONE);
4871ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim            }
488b7b02f5cac8b760805d98ddbfe03e0730bee6709Sungsoo Lim            updateControlLayoutHeight();
4891ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim        }
4901ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim    }
4911ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim
4921ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim    private void updatePlaybackControl() {
4931ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim        if (mCustomControlView == null && (mDescription != null || mState != null)) {
4941ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim            mPlaybackControl.setVisibility(View.VISIBLE);
4951ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim            CharSequence title = mDescription == null ? null : mDescription.getTitle();
4961ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim            boolean hasTitle = !TextUtils.isEmpty(title);
4971ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim
4981ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim            CharSequence subtitle = mDescription == null ? null : mDescription.getSubtitle();
4991ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim            boolean hasSubtitle = !TextUtils.isEmpty(subtitle);
5001ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim
5011ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim            if (!hasTitle && !hasSubtitle) {
5021ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                if (mRoute.getPresentationDisplayId()
5031ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                        != MediaRouter.RouteInfo.PRESENTATION_DISPLAY_ID_NONE) {
5041ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                    // The user is currently casting screen.
5051ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                    mTitleView.setText(R.string.mr_controller_casting_screen);
5061ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                } else {
5071ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                    mTitleView.setText((mState == null
5081ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                            || mState.getState() == PlaybackStateCompat.STATE_NONE)
5091ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                                    ? R.string.mr_controller_no_media_selected
5101ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                                    : R.string.mr_controller_no_info_available);
5111ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                }
5121ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                mTitleView.setEnabled(false);
5131ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                mTitleView.setVisibility(View.VISIBLE);
5141ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                mSubtitleView.setVisibility(View.GONE);
5151ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim            } else {
5161ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                mTitleView.setText(title);
5171ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                mTitleView.setEnabled(hasTitle);
5181ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                mTitleView.setVisibility(hasTitle ? View.VISIBLE : View.GONE);
5191ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                mSubtitleView.setText(subtitle);
5201ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                mSubtitleView.setVisibility(hasSubtitle ? View.VISIBLE : View.GONE);
5211ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim            }
5221ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim            if (mState != null) {
5231ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                boolean isPlaying = mState.getState() == PlaybackStateCompat.STATE_BUFFERING
5241ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                        || mState.getState() == PlaybackStateCompat.STATE_PLAYING;
5251ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                boolean supportsPlay = (mState.getActions() & (PlaybackStateCompat.ACTION_PLAY
5261ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                        | PlaybackStateCompat.ACTION_PLAY_PAUSE)) != 0;
5271ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                boolean supportsPause = (mState.getActions() & (PlaybackStateCompat.ACTION_PAUSE
5281ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                        | PlaybackStateCompat.ACTION_PLAY_PAUSE)) != 0;
5291ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                if (isPlaying && supportsPause) {
5301ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                    mPlayPauseButton.setVisibility(View.VISIBLE);
5311ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                    mPlayPauseButton.setImageResource(MediaRouterThemeHelper.getThemeResource(
5321ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                            getContext(), R.attr.mediaRoutePauseDrawable));
5331ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                    mPlayPauseButton.setContentDescription(getContext().getResources()
5341ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                            .getText(R.string.mr_controller_pause));
5351ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                } else if (!isPlaying && supportsPlay) {
5361ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                    mPlayPauseButton.setVisibility(View.VISIBLE);
5371ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                    mPlayPauseButton.setImageResource(MediaRouterThemeHelper.getThemeResource(
5381ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                            getContext(), R.attr.mediaRoutePlayDrawable));
5391ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                    mPlayPauseButton.setContentDescription(getContext().getResources()
5401ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                            .getText(R.string.mr_controller_play));
5411ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                } else {
5421ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                    mPlayPauseButton.setVisibility(View.GONE);
5431ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                }
5441ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim            }
5451ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim        } else {
5461ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim            mPlaybackControl.setVisibility(View.GONE);
5471ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim        }
548b7b02f5cac8b760805d98ddbfe03e0730bee6709Sungsoo Lim        updateControlLayoutHeight();
5491ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim    }
5501ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim
551b7b02f5cac8b760805d98ddbfe03e0730bee6709Sungsoo Lim    private void updateControlLayoutHeight() {
552b7b02f5cac8b760805d98ddbfe03e0730bee6709Sungsoo Lim        // TODO: Update the top and bottom padding of the control layout according to the display
5531ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim        // height.
5541ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim        mDividerView.setVisibility((mVolumeControl.getVisibility() == View.VISIBLE
5551ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                && mPlaybackControl.getVisibility() == View.VISIBLE)
5561ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                ? View.VISIBLE : View.GONE);
5571ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim        mControlLayout.setVisibility((mVolumeControl.getVisibility() == View.GONE
5581ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                && mPlaybackControl.getVisibility() == View.GONE)
5591ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                ? View.GONE : View.VISIBLE);
560f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah    }
561f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah
5622b274bd3e06bd33c9b2a0851256afcda94d96395Dongwon Kang    private void updateControlFrameLayout() {
5632b274bd3e06bd33c9b2a0851256afcda94d96395Dongwon Kang        if (!mNeedToAdjustControlFrameLayout) {
5642b274bd3e06bd33c9b2a0851256afcda94d96395Dongwon Kang            return;
5652b274bd3e06bd33c9b2a0851256afcda94d96395Dongwon Kang        }
5662b274bd3e06bd33c9b2a0851256afcda94d96395Dongwon Kang        int height;
5672b274bd3e06bd33c9b2a0851256afcda94d96395Dongwon Kang        if (mArtView.getVisibility() == View.GONE) {
5682b274bd3e06bd33c9b2a0851256afcda94d96395Dongwon Kang            height = LinearLayout.LayoutParams.WRAP_CONTENT;
5692b274bd3e06bd33c9b2a0851256afcda94d96395Dongwon Kang        } else if (!mIsGroupExpanded) {
5702b274bd3e06bd33c9b2a0851256afcda94d96395Dongwon Kang            height = mArtView.getHeight() + mControlLayout.getHeight();
5712b274bd3e06bd33c9b2a0851256afcda94d96395Dongwon Kang        } else {
5722b274bd3e06bd33c9b2a0851256afcda94d96395Dongwon Kang            if (mVolumeGroupList.getAdapter().getCount() <= 2) {
5732b274bd3e06bd33c9b2a0851256afcda94d96395Dongwon Kang                // Push the controls up and cover the artwork.
5742b274bd3e06bd33c9b2a0851256afcda94d96395Dongwon Kang                height = mArtView.getHeight() + mControlLayout.getHeight()
5752b274bd3e06bd33c9b2a0851256afcda94d96395Dongwon Kang                        - mVolumeGroupList.getHeight();
5762b274bd3e06bd33c9b2a0851256afcda94d96395Dongwon Kang            } else {
5772b274bd3e06bd33c9b2a0851256afcda94d96395Dongwon Kang                // If there are 3 or more, the controls completely cover the artwork.
5782b274bd3e06bd33c9b2a0851256afcda94d96395Dongwon Kang                height = mControlLayout.getHeight();
5792b274bd3e06bd33c9b2a0851256afcda94d96395Dongwon Kang            }
5802b274bd3e06bd33c9b2a0851256afcda94d96395Dongwon Kang        }
58186a802c8d09983d8725cccf59217e65d3e0c6373Jae Seo        mDefaultControlLayout.setLayoutParams(
58286a802c8d09983d8725cccf59217e65d3e0c6373Jae Seo                new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, height));
5832b274bd3e06bd33c9b2a0851256afcda94d96395Dongwon Kang        mNeedToAdjustControlFrameLayout = false;
5842b274bd3e06bd33c9b2a0851256afcda94d96395Dongwon Kang    }
5852b274bd3e06bd33c9b2a0851256afcda94d96395Dongwon Kang
586f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah    private boolean isVolumeControlAvailable() {
587f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah        return mVolumeControlEnabled && mRoute.getVolumeHandling() ==
588f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah                MediaRouter.RouteInfo.PLAYBACK_VOLUME_VARIABLE;
589f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah    }
590f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah
59113d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim    private void updateArtView() {
5922b274bd3e06bd33c9b2a0851256afcda94d96395Dongwon Kang        mNeedToAdjustControlFrameLayout = true;
59313d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim        if (!(mArtView.getDrawable() instanceof BitmapDrawable)) {
594bfb90b6717bb46535d747aa50045a206965542d0Jae Seo            mArtView.setVisibility(View.GONE);
59513d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim            return;
59613d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim        }
59713d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim        Bitmap art = ((BitmapDrawable) mArtView.getDrawable()).getBitmap();
59813d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim        if (art == null) {
599bfb90b6717bb46535d747aa50045a206965542d0Jae Seo            mArtView.setVisibility(View.GONE);
60013d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim            return;
60113d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim        }
60213d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim        int desiredArtHeight = getDesiredArtHeight(art.getWidth(), art.getHeight());
60313d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim        DisplayMetrics displayMetrics = getContext().getResources().getDisplayMetrics();
60413d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim        int dialogWidth = displayMetrics.widthPixels < displayMetrics.heightPixels
60513d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim                ? mDialogWidthPortrait : mDialogWidthLandscape;
60613d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim        View decorView = getWindow().getDecorView();
60713d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim        decorView.measure(dialogWidth, View.MeasureSpec.UNSPECIFIED);
60813d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim        // Show art if and only if it fits in the screen.
60913d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim        if (mArtView.getVisibility() == View.GONE) {
61013d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim            if (decorView.getMeasuredHeight() + desiredArtHeight <= displayMetrics.heightPixels) {
61113d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim                mArtView.setVisibility(View.VISIBLE);
61213d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim                mArtView.setMaxHeight(desiredArtHeight);
61313d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim            }
61413d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim        } else {
61513d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim            if (decorView.getMeasuredHeight() - mArtView.getMeasuredHeight() + desiredArtHeight
61613d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim                    <= displayMetrics.heightPixels) {
61713d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim                mArtView.setMaxHeight(desiredArtHeight);
61813d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim            } else {
61913d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim                mArtView.setVisibility(View.GONE);
62013d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim            }
62113d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim        }
62213d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim    }
62313d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim
62486a802c8d09983d8725cccf59217e65d3e0c6373Jae Seo    private static void setVolumeSliderColor(SeekBar volumeSlider, int color) {
62586a802c8d09983d8725cccf59217e65d3e0c6373Jae Seo        volumeSlider.getProgressDrawable().setColorFilter(color, PorterDuff.Mode.SRC_IN);
62686a802c8d09983d8725cccf59217e65d3e0c6373Jae Seo        if (Build.VERSION.SDK_INT >= 16) {
62786a802c8d09983d8725cccf59217e65d3e0c6373Jae Seo            SeekBarJellybean.getThumb(volumeSlider).setColorFilter(color, PorterDuff.Mode.SRC_IN);
62886a802c8d09983d8725cccf59217e65d3e0c6373Jae Seo        }
62986a802c8d09983d8725cccf59217e65d3e0c6373Jae Seo    }
63086a802c8d09983d8725cccf59217e65d3e0c6373Jae Seo
63113d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim    /**
63213d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim     * Returns desired art height to fit into controller dialog.
63313d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim     */
63413d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim    private int getDesiredArtHeight(int originalWidth, int originalHeight) {
6354ec1a0371ebb43ba1537354becb9241c105d2fb8Jaewan Kim        int dialogWidth = getWindow().getAttributes().width - mDialogPaddingHorizontal;
63613d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim        if (originalWidth >= originalHeight) {
63713d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim            // For landscape art, fit width to dialog width.
6385716b49c08ac172c06fdced848ec8ab599174970Jaewan Kim            return (int) ((float) dialogWidth * originalHeight / originalWidth + 0.5f);
63913d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim        }
64013d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim        // For portrait art, fit height to 16:9 ratio case's height.
6415716b49c08ac172c06fdced848ec8ab599174970Jaewan Kim        return (int) ((float) dialogWidth * 9 / 16 + 0.5f);
64213d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim    }
64313d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim
64411417b1cfde8f1749905f2d735623af9214148afJeff Brown    private final class MediaRouterCallback extends MediaRouter.Callback {
64511417b1cfde8f1749905f2d735623af9214148afJeff Brown        @Override
64611417b1cfde8f1749905f2d735623af9214148afJeff Brown        public void onRouteUnselected(MediaRouter router, MediaRouter.RouteInfo route) {
64711417b1cfde8f1749905f2d735623af9214148afJeff Brown            update();
64811417b1cfde8f1749905f2d735623af9214148afJeff Brown        }
64911417b1cfde8f1749905f2d735623af9214148afJeff Brown
65011417b1cfde8f1749905f2d735623af9214148afJeff Brown        @Override
65111417b1cfde8f1749905f2d735623af9214148afJeff Brown        public void onRouteChanged(MediaRouter router, MediaRouter.RouteInfo route) {
65211417b1cfde8f1749905f2d735623af9214148afJeff Brown            update();
65311417b1cfde8f1749905f2d735623af9214148afJeff Brown        }
65411417b1cfde8f1749905f2d735623af9214148afJeff Brown
65511417b1cfde8f1749905f2d735623af9214148afJeff Brown        @Override
65611417b1cfde8f1749905f2d735623af9214148afJeff Brown        public void onRouteVolumeChanged(MediaRouter router, MediaRouter.RouteInfo route) {
65711417b1cfde8f1749905f2d735623af9214148afJeff Brown            if (route == mRoute) {
6581ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                updateVolumeControl();
65994be6100218126ce6a08bf1f56209578500b361fRoboErik            }
66094be6100218126ce6a08bf1f56209578500b361fRoboErik        }
66194be6100218126ce6a08bf1f56209578500b361fRoboErik    }
66294be6100218126ce6a08bf1f56209578500b361fRoboErik
66394be6100218126ce6a08bf1f56209578500b361fRoboErik    private final class MediaControllerCallback extends MediaControllerCompat.Callback {
66494be6100218126ce6a08bf1f56209578500b361fRoboErik        @Override
66594be6100218126ce6a08bf1f56209578500b361fRoboErik        public void onSessionDestroyed() {
66694be6100218126ce6a08bf1f56209578500b361fRoboErik            if (mMediaController != null) {
66794be6100218126ce6a08bf1f56209578500b361fRoboErik                mMediaController.unregisterCallback(mControllerCallback);
66894be6100218126ce6a08bf1f56209578500b361fRoboErik                mMediaController = null;
66994be6100218126ce6a08bf1f56209578500b361fRoboErik            }
67094be6100218126ce6a08bf1f56209578500b361fRoboErik        }
67194be6100218126ce6a08bf1f56209578500b361fRoboErik
67294be6100218126ce6a08bf1f56209578500b361fRoboErik        @Override
67394be6100218126ce6a08bf1f56209578500b361fRoboErik        public void onPlaybackStateChanged(PlaybackStateCompat state) {
67494be6100218126ce6a08bf1f56209578500b361fRoboErik            mState = state;
67594be6100218126ce6a08bf1f56209578500b361fRoboErik            update();
67694be6100218126ce6a08bf1f56209578500b361fRoboErik        }
67794be6100218126ce6a08bf1f56209578500b361fRoboErik
67894be6100218126ce6a08bf1f56209578500b361fRoboErik        @Override
67994be6100218126ce6a08bf1f56209578500b361fRoboErik        public void onMetadataChanged(MediaMetadataCompat metadata) {
68094be6100218126ce6a08bf1f56209578500b361fRoboErik            mDescription = metadata == null ? null : metadata.getDescription();
68194be6100218126ce6a08bf1f56209578500b361fRoboErik            update();
68294be6100218126ce6a08bf1f56209578500b361fRoboErik        }
68394be6100218126ce6a08bf1f56209578500b361fRoboErik    }
68494be6100218126ce6a08bf1f56209578500b361fRoboErik
68594be6100218126ce6a08bf1f56209578500b361fRoboErik    private final class ClickListener implements View.OnClickListener {
68694be6100218126ce6a08bf1f56209578500b361fRoboErik        @Override
68794be6100218126ce6a08bf1f56209578500b361fRoboErik        public void onClick(View v) {
68894be6100218126ce6a08bf1f56209578500b361fRoboErik            int id = v.getId();
6891ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim            if (id == R.id.mr_button_stop || id == R.id.mr_button_disconnect) {
69094be6100218126ce6a08bf1f56209578500b361fRoboErik                if (mRoute.isSelected()) {
6911ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim                    mRouter.unselect(id == R.id.mr_button_stop ?
69294be6100218126ce6a08bf1f56209578500b361fRoboErik                            MediaRouter.UNSELECT_REASON_STOPPED :
69394be6100218126ce6a08bf1f56209578500b361fRoboErik                            MediaRouter.UNSELECT_REASON_DISCONNECTED);
69494be6100218126ce6a08bf1f56209578500b361fRoboErik                }
69594be6100218126ce6a08bf1f56209578500b361fRoboErik                dismiss();
6967ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim            } else if (id == R.id.mr_control_play_pause) {
69794be6100218126ce6a08bf1f56209578500b361fRoboErik                if (mMediaController != null && mState != null) {
69894be6100218126ce6a08bf1f56209578500b361fRoboErik                    if (mState.getState() == PlaybackStateCompat.STATE_PLAYING) {
69994be6100218126ce6a08bf1f56209578500b361fRoboErik                        mMediaController.getTransportControls().pause();
70094be6100218126ce6a08bf1f56209578500b361fRoboErik                    } else {
70194be6100218126ce6a08bf1f56209578500b361fRoboErik                        mMediaController.getTransportControls().play();
70294be6100218126ce6a08bf1f56209578500b361fRoboErik                    }
70394be6100218126ce6a08bf1f56209578500b361fRoboErik                }
7041ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim            } else if (id == R.id.mr_close) {
705b48ccf48b0281e69262fc643d0def898aede407bSungsoo Lim                dismiss();
70611417b1cfde8f1749905f2d735623af9214148afJeff Brown            }
70711417b1cfde8f1749905f2d735623af9214148afJeff Brown        }
70811417b1cfde8f1749905f2d735623af9214148afJeff Brown    }
709005482649154d0970693b3967241eb4d2cb22003Jaewan Kim
7106051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo    private class VolumeGroupAdapter extends ArrayAdapter<MediaRouter.RouteInfo> {
7110e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo        final static float DISABLED_ALPHA = .3f;
7120e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo
7136051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo        final OnSeekBarChangeListener mOnSeekBarChangeListener = new OnSeekBarChangeListener() {
7146051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo            @Override
7156051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
7166051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo                if (fromUser) {
7176051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo                    int position = (int) seekBar.getTag();
7186051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo                    getGroup().getRouteAt(position).requestSetVolume(progress);
7196051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo                }
7206051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo            }
7216051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo
7226051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo            @Override
7236051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo            public void onStartTrackingTouch(SeekBar seekBar) {
7246051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo                // TODO: Implement
7256051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo            }
7266051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo
7276051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo            @Override
7286051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo            public void onStopTrackingTouch(SeekBar seekBar) {
7296051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo                // TODO: Implement
7306051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo            }
7316051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo        };
7326051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo
7336051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo        public VolumeGroupAdapter(Context context, List<MediaRouter.RouteInfo> objects) {
7346051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo            super(context, 0, objects);
7356051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo        }
7366051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo
7376051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo        @Override
7386051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo        public View getView(final int position, View convertView, ViewGroup parent) {
7396051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo            View v = convertView;
7406051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo            if (v == null) {
7416051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo                v = LayoutInflater.from(getContext()).inflate(
742a09c7b30d3a5c53281db955eabce171e1aec6feaSungsoo Lim                        R.layout.mr_controller_volume_item, null);
74386a802c8d09983d8725cccf59217e65d3e0c6373Jae Seo                setVolumeSliderColor(
74486a802c8d09983d8725cccf59217e65d3e0c6373Jae Seo                        (SeekBar) v.findViewById(R.id.mr_volume_slider), mVolumeSliderColor);
7456051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo            }
7466051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo            MediaRouter.RouteInfo route = getItem(position);
7476051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo            if (route != null) {
7480e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo                boolean isEnabled = route.isEnabled();
7490e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo
7507ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim                TextView routeName = (TextView) v.findViewById(R.id.mr_name);
7510e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo                routeName.setEnabled(isEnabled);
7520e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo                routeName.setText(route.getName());
7536051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo
7547ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim                SeekBar volumeSlider = (SeekBar) v.findViewById(R.id.mr_volume_slider);
7550e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo                volumeSlider.setEnabled(isEnabled);
7566051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo                volumeSlider.setTag(position);
7570e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo                if (isEnabled) {
7580e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo                    if (route.getVolumeHandling()
7590e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo                            == MediaRouter.RouteInfo.PLAYBACK_VOLUME_VARIABLE) {
7600e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo                        volumeSlider.setMax(route.getVolumeMax());
7610e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo                        volumeSlider.setProgress(route.getVolume());
7620e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo                        volumeSlider.setOnSeekBarChangeListener(mOnSeekBarChangeListener);
7630e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo                    } else {
7640e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo                        volumeSlider.setMax(100);
7650e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo                        volumeSlider.setProgress(100);
7660e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo                        volumeSlider.setEnabled(false);
7670e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo                    }
7680e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo                }
769418c688351713e9349227262163eef752a8e7ce6Jae Seo                if (Build.VERSION.SDK_INT >= 16) {
770418c688351713e9349227262163eef752a8e7ce6Jae Seo                    SeekBarJellybean.getThumb(volumeSlider).mutate().setAlpha(isEnabled ? 255 : 0);
771418c688351713e9349227262163eef752a8e7ce6Jae Seo                    // TODO: Still see an artifact even though the thumb is transparent. Remove it.
772418c688351713e9349227262163eef752a8e7ce6Jae Seo                }
7730e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo
7740e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo                ImageView volumeItemIcon =
7757ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim                        (ImageView) v.findViewById(R.id.mr_volume_item_icon);
77677367b4a1871417198d0399d9ad074314c758567Jae Seo                volumeItemIcon.setAlpha(isEnabled ? 255 : (int) (255 * DISABLED_ALPHA));
7776051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo            }
7786051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo            return v;
7796051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo        }
7806051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo    }
7816051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo
782005482649154d0970693b3967241eb4d2cb22003Jaewan Kim    private class FetchArtTask extends AsyncTask<Void, Void, Bitmap> {
783005482649154d0970693b3967241eb4d2cb22003Jaewan Kim        private int mBackgroundColor;
784005482649154d0970693b3967241eb4d2cb22003Jaewan Kim
785005482649154d0970693b3967241eb4d2cb22003Jaewan Kim        @Override
786005482649154d0970693b3967241eb4d2cb22003Jaewan Kim        protected Bitmap doInBackground(Void... arg) {
78713d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim            Bitmap art = null;
788005482649154d0970693b3967241eb4d2cb22003Jaewan Kim            if (mDescription == null) {
789005482649154d0970693b3967241eb4d2cb22003Jaewan Kim                return null;
790005482649154d0970693b3967241eb4d2cb22003Jaewan Kim            }
791005482649154d0970693b3967241eb4d2cb22003Jaewan Kim            if (mDescription.getIconBitmap() != null) {
79213d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim                art = mDescription.getIconBitmap();
793005482649154d0970693b3967241eb4d2cb22003Jaewan Kim            } else if (mDescription.getIconUri() != null) {
794005482649154d0970693b3967241eb4d2cb22003Jaewan Kim                Uri iconUri = mDescription.getIconUri();
795005482649154d0970693b3967241eb4d2cb22003Jaewan Kim                String scheme = iconUri.getScheme();
796005482649154d0970693b3967241eb4d2cb22003Jaewan Kim                if (!(ContentResolver.SCHEME_ANDROID_RESOURCE.equals(scheme)
797005482649154d0970693b3967241eb4d2cb22003Jaewan Kim                        || ContentResolver.SCHEME_CONTENT.equals(scheme)
798005482649154d0970693b3967241eb4d2cb22003Jaewan Kim                        || ContentResolver.SCHEME_FILE.equals(scheme))) {
799005482649154d0970693b3967241eb4d2cb22003Jaewan Kim                    Log.w(TAG, "Icon Uri should point to local resources.");
800005482649154d0970693b3967241eb4d2cb22003Jaewan Kim                    return null;
801005482649154d0970693b3967241eb4d2cb22003Jaewan Kim                }
802005482649154d0970693b3967241eb4d2cb22003Jaewan Kim                BufferedInputStream stream = null;
803005482649154d0970693b3967241eb4d2cb22003Jaewan Kim                try {
804005482649154d0970693b3967241eb4d2cb22003Jaewan Kim                    stream = new BufferedInputStream(
805005482649154d0970693b3967241eb4d2cb22003Jaewan Kim                            getContext().getContentResolver().openInputStream(iconUri));
806005482649154d0970693b3967241eb4d2cb22003Jaewan Kim
80713d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim                    // Query art size.
808005482649154d0970693b3967241eb4d2cb22003Jaewan Kim                    BitmapFactory.Options options = new BitmapFactory.Options();
809005482649154d0970693b3967241eb4d2cb22003Jaewan Kim                    options.inJustDecodeBounds = true;
810005482649154d0970693b3967241eb4d2cb22003Jaewan Kim                    BitmapFactory.decodeStream(stream, null, options);
81113d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim                    if (options.outWidth == 0 || options.outHeight == 0) {
81213d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim                        return null;
81313d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim                    }
81413d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim                    // Rewind the stream in order to restart art decoding.
815005482649154d0970693b3967241eb4d2cb22003Jaewan Kim                    try {
816005482649154d0970693b3967241eb4d2cb22003Jaewan Kim                        stream.reset();
817005482649154d0970693b3967241eb4d2cb22003Jaewan Kim                    } catch (IOException e) {
818005482649154d0970693b3967241eb4d2cb22003Jaewan Kim                        // Failed to rewind the stream, try to reopen it.
819005482649154d0970693b3967241eb4d2cb22003Jaewan Kim                        stream.close();
820005482649154d0970693b3967241eb4d2cb22003Jaewan Kim                        stream = new BufferedInputStream(getContext().getContentResolver()
821005482649154d0970693b3967241eb4d2cb22003Jaewan Kim                                .openInputStream(iconUri));
822005482649154d0970693b3967241eb4d2cb22003Jaewan Kim                    }
82313d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim                    // Calculate required size to decode the art and possibly resize it.
824005482649154d0970693b3967241eb4d2cb22003Jaewan Kim                    options.inJustDecodeBounds = false;
82513d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim                    int reqHeight = getDesiredArtHeight(options.outWidth, options.outHeight);
82613d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim                    int ratio = options.outHeight / reqHeight;
827005482649154d0970693b3967241eb4d2cb22003Jaewan Kim                    options.inSampleSize = Math.max(1, Integer.highestOneBit(ratio));
828005482649154d0970693b3967241eb4d2cb22003Jaewan Kim                    if (isCancelled()) {
829005482649154d0970693b3967241eb4d2cb22003Jaewan Kim                        return null;
830005482649154d0970693b3967241eb4d2cb22003Jaewan Kim                    }
83113d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim                    art = BitmapFactory.decodeStream(stream, null, options);
832005482649154d0970693b3967241eb4d2cb22003Jaewan Kim                } catch (IOException e){
833005482649154d0970693b3967241eb4d2cb22003Jaewan Kim                    Log.w(TAG, "Unable to open content: " + iconUri, e);
834005482649154d0970693b3967241eb4d2cb22003Jaewan Kim                } finally {
835005482649154d0970693b3967241eb4d2cb22003Jaewan Kim                    if (stream != null) {
836005482649154d0970693b3967241eb4d2cb22003Jaewan Kim                        try {
837005482649154d0970693b3967241eb4d2cb22003Jaewan Kim                            stream.close();
838005482649154d0970693b3967241eb4d2cb22003Jaewan Kim                        } catch (IOException e) {
839005482649154d0970693b3967241eb4d2cb22003Jaewan Kim                        }
840005482649154d0970693b3967241eb4d2cb22003Jaewan Kim                    }
841005482649154d0970693b3967241eb4d2cb22003Jaewan Kim                }
842005482649154d0970693b3967241eb4d2cb22003Jaewan Kim            }
843145e93b13dd025b278665494e7be0c15b8df5986Jaewan Kim            if (art != null && art.getWidth() < art.getHeight()) {
844145e93b13dd025b278665494e7be0c15b8df5986Jaewan Kim                // Portrait art requires background color.
845145e93b13dd025b278665494e7be0c15b8df5986Jaewan Kim                Palette palette = new Palette.Builder(art).maximumColorCount(1).generate();
846145e93b13dd025b278665494e7be0c15b8df5986Jaewan Kim                mBackgroundColor = (palette.getSwatches() == null)
847145e93b13dd025b278665494e7be0c15b8df5986Jaewan Kim                        ? 0 : palette.getSwatches().get(0).getRgb();
848005482649154d0970693b3967241eb4d2cb22003Jaewan Kim            }
84913d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim            return art;
850005482649154d0970693b3967241eb4d2cb22003Jaewan Kim        }
851005482649154d0970693b3967241eb4d2cb22003Jaewan Kim
852005482649154d0970693b3967241eb4d2cb22003Jaewan Kim        @Override
853005482649154d0970693b3967241eb4d2cb22003Jaewan Kim        protected void onCancelled() {
854005482649154d0970693b3967241eb4d2cb22003Jaewan Kim            mFetchArtTask = null;
855005482649154d0970693b3967241eb4d2cb22003Jaewan Kim        }
856005482649154d0970693b3967241eb4d2cb22003Jaewan Kim
857005482649154d0970693b3967241eb4d2cb22003Jaewan Kim        @Override
85813d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim        protected void onPostExecute(Bitmap art) {
859005482649154d0970693b3967241eb4d2cb22003Jaewan Kim            mFetchArtTask = null;
86013d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim            mArtView.setImageBitmap(art);
86113d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim            mArtView.setBackgroundColor(mBackgroundColor);
86213d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim            updateArtView();
863005482649154d0970693b3967241eb4d2cb22003Jaewan Kim        }
864005482649154d0970693b3967241eb4d2cb22003Jaewan Kim    }
8656051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo}
866