111417b1cfde8f1749905f2d735623af9214148afJeff Brown/* 2ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas * Copyright 2018 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 17ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikaspackage androidx.mediarouter.app; 1811417b1cfde8f1749905f2d735623af9214148afJeff Brown 196a39e73d20f14bed34f6bd9bc61b5b59d5050477Donghyun Choimport static android.support.v4.media.session.PlaybackStateCompat.ACTION_PAUSE; 206a39e73d20f14bed34f6bd9bc61b5b59d5050477Donghyun Choimport static android.support.v4.media.session.PlaybackStateCompat.ACTION_PLAY; 216a39e73d20f14bed34f6bd9bc61b5b59d5050477Donghyun Choimport static android.support.v4.media.session.PlaybackStateCompat.ACTION_PLAY_PAUSE; 226a39e73d20f14bed34f6bd9bc61b5b59d5050477Donghyun Choimport static android.support.v4.media.session.PlaybackStateCompat.ACTION_STOP; 236a39e73d20f14bed34f6bd9bc61b5b59d5050477Donghyun Cho 24f291fbba316ca92573d84dbe37e48e9d83181318Jae Seoimport android.app.PendingIntent; 25005482649154d0970693b3967241eb4d2cb22003Jaewan Kimimport android.content.ContentResolver; 2611417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.content.Context; 27c5738b858579021cc89fffd8a891b4c5ea8c0f83Jaewan Kimimport android.content.res.Resources; 28005482649154d0970693b3967241eb4d2cb22003Jaewan Kimimport android.graphics.Bitmap; 29005482649154d0970693b3967241eb4d2cb22003Jaewan Kimimport android.graphics.BitmapFactory; 302c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kimimport android.graphics.Rect; 3113d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kimimport android.graphics.drawable.BitmapDrawable; 32005482649154d0970693b3967241eb4d2cb22003Jaewan Kimimport android.net.Uri; 33005482649154d0970693b3967241eb4d2cb22003Jaewan Kimimport android.os.AsyncTask; 3411417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.os.Bundle; 3594be6100218126ce6a08bf1f56209578500b361fRoboErikimport android.os.RemoteException; 3687654ffe5c675519fd2a611c8fad40ee0979011eDonghyun Choimport android.os.SystemClock; 3794be6100218126ce6a08bf1f56209578500b361fRoboErikimport android.support.v4.media.MediaDescriptionCompat; 3894be6100218126ce6a08bf1f56209578500b361fRoboErikimport android.support.v4.media.MediaMetadataCompat; 3994be6100218126ce6a08bf1f56209578500b361fRoboErikimport android.support.v4.media.session.MediaSessionCompat; 4094be6100218126ce6a08bf1f56209578500b361fRoboErikimport android.support.v4.media.session.PlaybackStateCompat; 4194be6100218126ce6a08bf1f56209578500b361fRoboErikimport android.text.TextUtils; 4294be6100218126ce6a08bf1f56209578500b361fRoboErikimport android.util.Log; 4311417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.view.KeyEvent; 446051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seoimport android.view.LayoutInflater; 4511417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.view.View; 4640dd800ece983a94ea6a26a27481da50f489e7c8Jaewan Kimimport android.view.View.MeasureSpec; 476051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seoimport android.view.ViewGroup; 4886dcb627078ea297c4337ed634fc3fe874e23897Jae Seoimport android.view.ViewTreeObserver; 49ee7ae661b02471fe598566b1e90adbacda240b0bJae Seoimport android.view.accessibility.AccessibilityEvent; 50ee7ae661b02471fe598566b1e90adbacda240b0bJae Seoimport android.view.accessibility.AccessibilityManager; 511c4fce94062e162e579d20134f0bac767bdf0964Donghyun Choimport android.view.animation.AccelerateDecelerateInterpolator; 521c4fce94062e162e579d20134f0bac767bdf0964Donghyun Choimport android.view.animation.AlphaAnimation; 5304b31a042cb2c18ffe6ccfba7309f6b8222678cdDongwon Kangimport android.view.animation.Animation; 541c4fce94062e162e579d20134f0bac767bdf0964Donghyun Choimport android.view.animation.AnimationSet; 551c4fce94062e162e579d20134f0bac767bdf0964Donghyun Choimport android.view.animation.AnimationUtils; 561c4fce94062e162e579d20134f0bac767bdf0964Donghyun Choimport android.view.animation.Interpolator; 5704b31a042cb2c18ffe6ccfba7309f6b8222678cdDongwon Kangimport android.view.animation.Transformation; 581c4fce94062e162e579d20134f0bac767bdf0964Donghyun Choimport android.view.animation.TranslateAnimation; 596051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seoimport android.widget.ArrayAdapter; 6011417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.widget.Button; 6111417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.widget.FrameLayout; 6294be6100218126ce6a08bf1f56209578500b361fRoboErikimport android.widget.ImageButton; 6394be6100218126ce6a08bf1f56209578500b361fRoboErikimport android.widget.ImageView; 64f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shahimport android.widget.LinearLayout; 657ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Limimport android.widget.RelativeLayout; 66f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shahimport android.widget.SeekBar; 6794be6100218126ce6a08bf1f56209578500b361fRoboErikimport android.widget.TextView; 68ee1b969af871a7015fc2df11f8d342a4e6cf40f0Hyundo Moon 69f2d1695bf23114f2a5d6bfc9e092a4bfcb5b2701Aurimas Liutikasimport androidx.appcompat.app.AlertDialog; 70f2d1695bf23114f2a5d6bfc9e092a4bfcb5b2701Aurimas Liutikasimport androidx.core.util.ObjectsCompat; 71f2d1695bf23114f2a5d6bfc9e092a4bfcb5b2701Aurimas Liutikasimport androidx.core.view.accessibility.AccessibilityEventCompat; 7224919ee8c30d91ec056cae6c4f578d7007cbe968Aurimas Liutikasimport android.support.v4.media.session.MediaControllerCompat; 73f2d1695bf23114f2a5d6bfc9e092a4bfcb5b2701Aurimas Liutikasimport androidx.mediarouter.R; 74f2d1695bf23114f2a5d6bfc9e092a4bfcb5b2701Aurimas Liutikasimport androidx.mediarouter.media.MediaRouteSelector; 75f2d1695bf23114f2a5d6bfc9e092a4bfcb5b2701Aurimas Liutikasimport androidx.mediarouter.media.MediaRouter; 76f2d1695bf23114f2a5d6bfc9e092a4bfcb5b2701Aurimas Liutikasimport androidx.palette.graphics.Palette; 77f2d1695bf23114f2a5d6bfc9e092a4bfcb5b2701Aurimas Liutikas 78005482649154d0970693b3967241eb4d2cb22003Jaewan Kimimport java.io.BufferedInputStream; 79005482649154d0970693b3967241eb4d2cb22003Jaewan Kimimport java.io.IOException; 801c4fce94062e162e579d20134f0bac767bdf0964Donghyun Choimport java.io.InputStream; 81376f4d5a03a3dfc9d4ca30074b3df3e424bd7e4bDonghyun Choimport java.net.URL; 82376f4d5a03a3dfc9d4ca30074b3df3e424bd7e4bDonghyun Choimport java.net.URLConnection; 831c4fce94062e162e579d20134f0bac767bdf0964Donghyun Choimport java.util.ArrayList; 84dbe6b4010999eaa31c5bbac520277391717c2ef0Sungsoo Limimport java.util.HashMap; 851c4fce94062e162e579d20134f0bac767bdf0964Donghyun Choimport java.util.HashSet; 866051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seoimport java.util.List; 87dbe6b4010999eaa31c5bbac520277391717c2ef0Sungsoo Limimport java.util.Map; 881c4fce94062e162e579d20134f0bac767bdf0964Donghyun Choimport java.util.Set; 89376f4d5a03a3dfc9d4ca30074b3df3e424bd7e4bDonghyun Choimport java.util.concurrent.TimeUnit; 90005482649154d0970693b3967241eb4d2cb22003Jaewan Kim 9111417b1cfde8f1749905f2d735623af9214148afJeff Brown/** 9211417b1cfde8f1749905f2d735623af9214148afJeff Brown * This class implements the route controller dialog for {@link MediaRouter}. 9311417b1cfde8f1749905f2d735623af9214148afJeff Brown * <p> 9411417b1cfde8f1749905f2d735623af9214148afJeff Brown * This dialog allows the user to control or disconnect from the currently selected route. 9511417b1cfde8f1749905f2d735623af9214148afJeff Brown * </p> 9611417b1cfde8f1749905f2d735623af9214148afJeff Brown * 9711417b1cfde8f1749905f2d735623af9214148afJeff Brown * @see MediaRouteButton 9811417b1cfde8f1749905f2d735623af9214148afJeff Brown * @see MediaRouteActionProvider 9911417b1cfde8f1749905f2d735623af9214148afJeff Brown */ 10089530d511efd566d53bedd9178454dd01d227c61Jae Seopublic class MediaRouteControllerDialog extends AlertDialog { 101ddec4bb519422d680d93911e95d252b620d09ba2Insun Kang // Tags should be less than 24 characters long (see docs for android.util.Log.isLoggable()) 102e2c6a94b6e4aab502f9b88dd3ff664bd90b25839Aurimas Liutikas static final String TAG = "MediaRouteCtrlDialog"; 103e2c6a94b6e4aab502f9b88dd3ff664bd90b25839Aurimas Liutikas static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); 10411417b1cfde8f1749905f2d735623af9214148afJeff Brown 105f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah // Time to wait before updating the volume when the user lets go of the seek bar 106f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah // to allow the route provider time to propagate the change and publish a new 107f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah // route descriptor. 108e2c6a94b6e4aab502f9b88dd3ff664bd90b25839Aurimas Liutikas static final int VOLUME_UPDATE_DELAY_MILLIS = 500; 109e2c6a94b6e4aab502f9b88dd3ff664bd90b25839Aurimas Liutikas static final int CONNECTION_TIMEOUT_MILLIS = (int) TimeUnit.SECONDS.toMillis(30L); 110f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah 11106991009e52024cbb3dde550988e06149e77a269Jae Seo private static final int BUTTON_NEUTRAL_RES_ID = android.R.id.button3; 112e2c6a94b6e4aab502f9b88dd3ff664bd90b25839Aurimas Liutikas static final int BUTTON_DISCONNECT_RES_ID = android.R.id.button2; 113e2c6a94b6e4aab502f9b88dd3ff664bd90b25839Aurimas Liutikas static final int BUTTON_STOP_RES_ID = android.R.id.button1; 11406991009e52024cbb3dde550988e06149e77a269Jae Seo 115e2c6a94b6e4aab502f9b88dd3ff664bd90b25839Aurimas Liutikas final MediaRouter mRouter; 11611417b1cfde8f1749905f2d735623af9214148afJeff Brown private final MediaRouterCallback mCallback; 117e2c6a94b6e4aab502f9b88dd3ff664bd90b25839Aurimas Liutikas final MediaRouter.RouteInfo mRoute; 11811417b1cfde8f1749905f2d735623af9214148afJeff Brown 119e2c6a94b6e4aab502f9b88dd3ff664bd90b25839Aurimas Liutikas Context mContext; 120eff7719415542ba819054863b0995f07742a7a8aJeff Brown private boolean mCreated; 121e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik private boolean mAttachedToWindow; 122e2148398ae5d03c22789aebc3d6359b5ff86c077Jae Seo 123f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seo private int mDialogContentWidth; 12411417b1cfde8f1749905f2d735623af9214148afJeff Brown 1257ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim private View mCustomControlView; 12611417b1cfde8f1749905f2d735623af9214148afJeff Brown 12711417b1cfde8f1749905f2d735623af9214148afJeff Brown private Button mDisconnectButton; 12894be6100218126ce6a08bf1f56209578500b361fRoboErik private Button mStopCastingButton; 1296a39e73d20f14bed34f6bd9bc61b5b59d5050477Donghyun Cho private ImageButton mPlaybackControlButton; 130b48ccf48b0281e69262fc643d0def898aede407bSungsoo Lim private ImageButton mCloseButton; 131328f1006c17ddeb3eb563580bcd6638e1cfb4320Jaewan Kim private MediaRouteExpandCollapseButton mGroupExpandCollapseButton; 13294be6100218126ce6a08bf1f56209578500b361fRoboErik 133c38d98f7bcd8effeb4921aeff6f6db8dfdba8de6Dongwon Kang private FrameLayout mExpandableAreaLayout; 134c38d98f7bcd8effeb4921aeff6f6db8dfdba8de6Dongwon Kang private LinearLayout mDialogAreaLayout; 135e2c6a94b6e4aab502f9b88dd3ff664bd90b25839Aurimas Liutikas FrameLayout mDefaultControlLayout; 136c38d98f7bcd8effeb4921aeff6f6db8dfdba8de6Dongwon Kang private FrameLayout mCustomControlLayout; 13794be6100218126ce6a08bf1f56209578500b361fRoboErik private ImageView mArtView; 1381ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim private TextView mTitleView; 1391ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim private TextView mSubtitleView; 1407ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim private TextView mRouteNameTextView; 14194be6100218126ce6a08bf1f56209578500b361fRoboErik 142f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah private boolean mVolumeControlEnabled = true; 14304b31a042cb2c18ffe6ccfba7309f6b8222678cdDongwon Kang // Layout for media controllers including play/pause button and the main volume slider. 1442c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim private LinearLayout mMediaMainControlLayout; 14570cae05dea9dc5bb23200e27d02fd0d9cf2d4b5bJae Seo private RelativeLayout mPlaybackControlLayout; 14670cae05dea9dc5bb23200e27d02fd0d9cf2d4b5bJae Seo private LinearLayout mVolumeControlLayout; 1471ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim private View mDividerView; 1481ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim 149e2c6a94b6e4aab502f9b88dd3ff664bd90b25839Aurimas Liutikas OverlayListView mVolumeGroupList; 150e2c6a94b6e4aab502f9b88dd3ff664bd90b25839Aurimas Liutikas VolumeGroupAdapter mVolumeGroupAdapter; 1512242344e6d1a2fe48c99926c39a87d1e0e4326cfDonghyun Cho private List<MediaRouter.RouteInfo> mGroupMemberRoutes; 152e2c6a94b6e4aab502f9b88dd3ff664bd90b25839Aurimas Liutikas Set<MediaRouter.RouteInfo> mGroupMemberRoutesAdded; 1531c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho private Set<MediaRouter.RouteInfo> mGroupMemberRoutesRemoved; 154e2c6a94b6e4aab502f9b88dd3ff664bd90b25839Aurimas Liutikas Set<MediaRouter.RouteInfo> mGroupMemberRoutesAnimatingWithBitmap; 155e2c6a94b6e4aab502f9b88dd3ff664bd90b25839Aurimas Liutikas SeekBar mVolumeSlider; 156e2c6a94b6e4aab502f9b88dd3ff664bd90b25839Aurimas Liutikas VolumeChangeListener mVolumeChangeListener; 157e2c6a94b6e4aab502f9b88dd3ff664bd90b25839Aurimas Liutikas MediaRouter.RouteInfo mRouteInVolumeSliderTouched; 158c5738b858579021cc89fffd8a891b4c5ea8c0f83Jaewan Kim private int mVolumeGroupListItemIconSize; 159c5738b858579021cc89fffd8a891b4c5ea8c0f83Jaewan Kim private int mVolumeGroupListItemHeight; 160c5738b858579021cc89fffd8a891b4c5ea8c0f83Jaewan Kim private int mVolumeGroupListMaxHeight; 161c5738b858579021cc89fffd8a891b4c5ea8c0f83Jaewan Kim private final int mVolumeGroupListPaddingTop; 162e2c6a94b6e4aab502f9b88dd3ff664bd90b25839Aurimas Liutikas Map<MediaRouter.RouteInfo, SeekBar> mVolumeSliderMap; 163e2c6a94b6e4aab502f9b88dd3ff664bd90b25839Aurimas Liutikas 164e2c6a94b6e4aab502f9b88dd3ff664bd90b25839Aurimas Liutikas MediaControllerCompat mMediaController; 165e2c6a94b6e4aab502f9b88dd3ff664bd90b25839Aurimas Liutikas MediaControllerCallback mControllerCallback; 166e2c6a94b6e4aab502f9b88dd3ff664bd90b25839Aurimas Liutikas PlaybackStateCompat mState; 167e2c6a94b6e4aab502f9b88dd3ff664bd90b25839Aurimas Liutikas MediaDescriptionCompat mDescription; 168e2c6a94b6e4aab502f9b88dd3ff664bd90b25839Aurimas Liutikas 169e2c6a94b6e4aab502f9b88dd3ff664bd90b25839Aurimas Liutikas FetchArtTask mFetchArtTask; 170e2c6a94b6e4aab502f9b88dd3ff664bd90b25839Aurimas Liutikas Bitmap mArtIconBitmap; 171e2c6a94b6e4aab502f9b88dd3ff664bd90b25839Aurimas Liutikas Uri mArtIconUri; 172e2c6a94b6e4aab502f9b88dd3ff664bd90b25839Aurimas Liutikas boolean mArtIconIsLoaded; 173e2c6a94b6e4aab502f9b88dd3ff664bd90b25839Aurimas Liutikas Bitmap mArtIconLoadedBitmap; 174e2c6a94b6e4aab502f9b88dd3ff664bd90b25839Aurimas Liutikas int mArtIconBackgroundColor; 175e2c6a94b6e4aab502f9b88dd3ff664bd90b25839Aurimas Liutikas 176e2c6a94b6e4aab502f9b88dd3ff664bd90b25839Aurimas Liutikas boolean mHasPendingUpdate; 177e2c6a94b6e4aab502f9b88dd3ff664bd90b25839Aurimas Liutikas boolean mPendingUpdateAnimationNeeded; 178e2c6a94b6e4aab502f9b88dd3ff664bd90b25839Aurimas Liutikas 179e2c6a94b6e4aab502f9b88dd3ff664bd90b25839Aurimas Liutikas boolean mIsGroupExpanded; 180e2c6a94b6e4aab502f9b88dd3ff664bd90b25839Aurimas Liutikas boolean mIsGroupListAnimating; 181e2c6a94b6e4aab502f9b88dd3ff664bd90b25839Aurimas Liutikas boolean mIsGroupListAnimationPending; 182e2c6a94b6e4aab502f9b88dd3ff664bd90b25839Aurimas Liutikas int mGroupListAnimationDurationMs; 1831c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho private int mGroupListFadeInDurationMs; 1841c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho private int mGroupListFadeOutDurationMs; 1851c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho 1861c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho private Interpolator mInterpolator; 1871c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho private Interpolator mLinearOutSlowInInterpolator; 1881c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho private Interpolator mFastOutSlowInInterpolator; 1891c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho private Interpolator mAccelerateDecelerateInterpolator; 19011417b1cfde8f1749905f2d735623af9214148afJeff Brown 191e2c6a94b6e4aab502f9b88dd3ff664bd90b25839Aurimas Liutikas final AccessibilityManager mAccessibilityManager; 192ee7ae661b02471fe598566b1e90adbacda240b0bJae Seo 193e2c6a94b6e4aab502f9b88dd3ff664bd90b25839Aurimas Liutikas Runnable mGroupListFadeInAnimation = new Runnable() { 1941c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho @Override 1951c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho public void run() { 1961c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho startGroupListFadeInAnimation(); 1971c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho } 1981c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho }; 1991c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho 20011417b1cfde8f1749905f2d735623af9214148afJeff Brown public MediaRouteControllerDialog(Context context) { 20111417b1cfde8f1749905f2d735623af9214148afJeff Brown this(context, 0); 20211417b1cfde8f1749905f2d735623af9214148afJeff Brown } 20311417b1cfde8f1749905f2d735623af9214148afJeff Brown 20411417b1cfde8f1749905f2d735623af9214148afJeff Brown public MediaRouteControllerDialog(Context context, int theme) { 2050fa3ac22663f0eecb24e7e68d6c4992e6fd32c19Christofer Ã…kersten super(context = MediaRouterThemeHelper.createThemedDialogContext(context, theme, true), 2060fa3ac22663f0eecb24e7e68d6c4992e6fd32c19Christofer Ã…kersten MediaRouterThemeHelper.createThemedDialogStyle(context)); 2074c5deffa8ddeb34accfded51e2be8573fbc1f301Dongwon Kang mContext = getContext(); 20811417b1cfde8f1749905f2d735623af9214148afJeff Brown 20994be6100218126ce6a08bf1f56209578500b361fRoboErik mControllerCallback = new MediaControllerCallback(); 2104448a8e5ed20d230cb838042ff73b6409106cf80Sungsoo Lim mRouter = MediaRouter.getInstance(mContext); 21111417b1cfde8f1749905f2d735623af9214148afJeff Brown mCallback = new MediaRouterCallback(); 21211417b1cfde8f1749905f2d735623af9214148afJeff Brown mRoute = mRouter.getSelectedRoute(); 213e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik setMediaSession(mRouter.getMediaSessionToken()); 2144448a8e5ed20d230cb838042ff73b6409106cf80Sungsoo Lim mVolumeGroupListPaddingTop = mContext.getResources().getDimensionPixelSize( 215c5738b858579021cc89fffd8a891b4c5ea8c0f83Jaewan Kim R.dimen.mr_controller_volume_group_list_padding_top); 216ee7ae661b02471fe598566b1e90adbacda240b0bJae Seo mAccessibilityManager = 2174448a8e5ed20d230cb838042ff73b6409106cf80Sungsoo Lim (AccessibilityManager) mContext.getSystemService(Context.ACCESSIBILITY_SERVICE); 2181c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho if (android.os.Build.VERSION.SDK_INT >= 21) { 2191c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho mLinearOutSlowInInterpolator = AnimationUtils.loadInterpolator(context, 2201c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho R.interpolator.mr_linear_out_slow_in); 2211c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho mFastOutSlowInInterpolator = AnimationUtils.loadInterpolator(context, 2221c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho R.interpolator.mr_fast_out_slow_in); 2231c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho } 2241c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho mAccelerateDecelerateInterpolator = new AccelerateDecelerateInterpolator(); 22511417b1cfde8f1749905f2d735623af9214148afJeff Brown } 22611417b1cfde8f1749905f2d735623af9214148afJeff Brown 22711417b1cfde8f1749905f2d735623af9214148afJeff Brown /** 22811417b1cfde8f1749905f2d735623af9214148afJeff Brown * Gets the route that this dialog is controlling. 22911417b1cfde8f1749905f2d735623af9214148afJeff Brown */ 23011417b1cfde8f1749905f2d735623af9214148afJeff Brown public MediaRouter.RouteInfo getRoute() { 23111417b1cfde8f1749905f2d735623af9214148afJeff Brown return mRoute; 23211417b1cfde8f1749905f2d735623af9214148afJeff Brown } 23311417b1cfde8f1749905f2d735623af9214148afJeff Brown 2346051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo private MediaRouter.RouteGroup getGroup() { 2356051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo if (mRoute instanceof MediaRouter.RouteGroup) { 2366051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo return (MediaRouter.RouteGroup) mRoute; 2376051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo } 2386051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo return null; 2396051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo } 2406051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo 24111417b1cfde8f1749905f2d735623af9214148afJeff Brown /** 24256d9fd2c2746f50e6a31e24b19e8671bba31a842Dongwon Kang * Provides the subclass an opportunity to create a view that will replace the default media 24356d9fd2c2746f50e6a31e24b19e8671bba31a842Dongwon Kang * controls for the currently playing content. 24411417b1cfde8f1749905f2d735623af9214148afJeff Brown * 24511417b1cfde8f1749905f2d735623af9214148afJeff Brown * @param savedInstanceState The dialog's saved instance state. 24611417b1cfde8f1749905f2d735623af9214148afJeff Brown * @return The media control view, or null if none. 24711417b1cfde8f1749905f2d735623af9214148afJeff Brown */ 24811417b1cfde8f1749905f2d735623af9214148afJeff Brown public View onCreateMediaControlView(Bundle savedInstanceState) { 24911417b1cfde8f1749905f2d735623af9214148afJeff Brown return null; 25011417b1cfde8f1749905f2d735623af9214148afJeff Brown } 25111417b1cfde8f1749905f2d735623af9214148afJeff Brown 25211417b1cfde8f1749905f2d735623af9214148afJeff Brown /** 25311417b1cfde8f1749905f2d735623af9214148afJeff Brown * Gets the media control view that was created by {@link #onCreateMediaControlView(Bundle)}. 25411417b1cfde8f1749905f2d735623af9214148afJeff Brown * 25511417b1cfde8f1749905f2d735623af9214148afJeff Brown * @return The media control view, or null if none. 25611417b1cfde8f1749905f2d735623af9214148afJeff Brown */ 25711417b1cfde8f1749905f2d735623af9214148afJeff Brown public View getMediaControlView() { 2587ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim return mCustomControlView; 25911417b1cfde8f1749905f2d735623af9214148afJeff Brown } 26011417b1cfde8f1749905f2d735623af9214148afJeff Brown 261eff7719415542ba819054863b0995f07742a7a8aJeff Brown /** 262f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah * Sets whether to enable the volume slider and volume control using the volume keys 263f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah * when the route supports it. 264f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah * <p> 265f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah * The default value is true. 266f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah * </p> 267f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah */ 268f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah public void setVolumeControlEnabled(boolean enable) { 269f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah if (mVolumeControlEnabled != enable) { 270f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah mVolumeControlEnabled = enable; 271f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah if (mCreated) { 27275322d1d57085c80a76d0d6db41426777dab08d0Donghyun Cho update(false); 273f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah } 274f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah } 275f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah } 276f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah 277f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah /** 278f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah * Returns whether to enable the volume slider and volume control using the volume keys 279f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah * when the route supports it. 280f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah */ 281f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah public boolean isVolumeControlEnabled() { 282f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah return mVolumeControlEnabled; 283f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah } 284f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah 285f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah /** 28694be6100218126ce6a08bf1f56209578500b361fRoboErik * Set the session to use for metadata and transport controls. The dialog 28794be6100218126ce6a08bf1f56209578500b361fRoboErik * will listen to changes on this session and update the UI automatically in 28894be6100218126ce6a08bf1f56209578500b361fRoboErik * response to changes. 28994be6100218126ce6a08bf1f56209578500b361fRoboErik * 29094be6100218126ce6a08bf1f56209578500b361fRoboErik * @param sessionToken The token for the session to use. 291eff7719415542ba819054863b0995f07742a7a8aJeff Brown */ 292e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik private void setMediaSession(MediaSessionCompat.Token sessionToken) { 29394be6100218126ce6a08bf1f56209578500b361fRoboErik if (mMediaController != null) { 29494be6100218126ce6a08bf1f56209578500b361fRoboErik mMediaController.unregisterCallback(mControllerCallback); 29594be6100218126ce6a08bf1f56209578500b361fRoboErik mMediaController = null; 29694be6100218126ce6a08bf1f56209578500b361fRoboErik } 29794be6100218126ce6a08bf1f56209578500b361fRoboErik if (sessionToken == null) { 29894be6100218126ce6a08bf1f56209578500b361fRoboErik return; 29994be6100218126ce6a08bf1f56209578500b361fRoboErik } 300e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik if (!mAttachedToWindow) { 301e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik return; 302e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 30394be6100218126ce6a08bf1f56209578500b361fRoboErik try { 3044c5deffa8ddeb34accfded51e2be8573fbc1f301Dongwon Kang mMediaController = new MediaControllerCompat(mContext, sessionToken); 30594be6100218126ce6a08bf1f56209578500b361fRoboErik } catch (RemoteException e) { 30694be6100218126ce6a08bf1f56209578500b361fRoboErik Log.e(TAG, "Error creating media controller in setMediaSession.", e); 30794be6100218126ce6a08bf1f56209578500b361fRoboErik } 30894be6100218126ce6a08bf1f56209578500b361fRoboErik if (mMediaController != null) { 30994be6100218126ce6a08bf1f56209578500b361fRoboErik mMediaController.registerCallback(mControllerCallback); 310eff7719415542ba819054863b0995f07742a7a8aJeff Brown } 31194be6100218126ce6a08bf1f56209578500b361fRoboErik MediaMetadataCompat metadata = mMediaController == null ? null 31294be6100218126ce6a08bf1f56209578500b361fRoboErik : mMediaController.getMetadata(); 31394be6100218126ce6a08bf1f56209578500b361fRoboErik mDescription = metadata == null ? null : metadata.getDescription(); 31494be6100218126ce6a08bf1f56209578500b361fRoboErik mState = mMediaController == null ? null : mMediaController.getPlaybackState(); 31575322d1d57085c80a76d0d6db41426777dab08d0Donghyun Cho updateArtIconIfNeeded(); 3161c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho update(false); 317eff7719415542ba819054863b0995f07742a7a8aJeff Brown } 318eff7719415542ba819054863b0995f07742a7a8aJeff Brown 319eff7719415542ba819054863b0995f07742a7a8aJeff Brown /** 32075dbda46b4ca20861e9d382b1662b3c34d20da8aInsun Kang * Gets the session to use for metadata and transport controls. 32194be6100218126ce6a08bf1f56209578500b361fRoboErik * 32275dbda46b4ca20861e9d382b1662b3c34d20da8aInsun Kang * @return The token for the session to use or null if none. 323eff7719415542ba819054863b0995f07742a7a8aJeff Brown */ 32494be6100218126ce6a08bf1f56209578500b361fRoboErik public MediaSessionCompat.Token getMediaSession() { 32594be6100218126ce6a08bf1f56209578500b361fRoboErik return mMediaController == null ? null : mMediaController.getSessionToken(); 326eff7719415542ba819054863b0995f07742a7a8aJeff Brown } 327eff7719415542ba819054863b0995f07742a7a8aJeff Brown 32811417b1cfde8f1749905f2d735623af9214148afJeff Brown @Override 32911417b1cfde8f1749905f2d735623af9214148afJeff Brown protected void onCreate(Bundle savedInstanceState) { 33011417b1cfde8f1749905f2d735623af9214148afJeff Brown super.onCreate(savedInstanceState); 33111417b1cfde8f1749905f2d735623af9214148afJeff Brown 332c38d98f7bcd8effeb4921aeff6f6db8dfdba8de6Dongwon Kang getWindow().setBackgroundDrawableResource(android.R.color.transparent); 333a09c7b30d3a5c53281db955eabce171e1aec6feaSungsoo Lim setContentView(R.layout.mr_controller_material_dialog_b); 334f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seo 33506991009e52024cbb3dde550988e06149e77a269Jae Seo // Remove the neutral button. 33606991009e52024cbb3dde550988e06149e77a269Jae Seo findViewById(BUTTON_NEUTRAL_RES_ID).setVisibility(View.GONE); 33706991009e52024cbb3dde550988e06149e77a269Jae Seo 33894be6100218126ce6a08bf1f56209578500b361fRoboErik ClickListener listener = new ClickListener(); 339d6748a7926ebb2450337f9f0ff4d445c980344e5Jeff Brown 340fa2e2acf79d791a90410025daad438968550d18cAlan Viverette mExpandableAreaLayout = findViewById(R.id.mr_expandable_area); 341c38d98f7bcd8effeb4921aeff6f6db8dfdba8de6Dongwon Kang mExpandableAreaLayout.setOnClickListener(new View.OnClickListener() { 342c38d98f7bcd8effeb4921aeff6f6db8dfdba8de6Dongwon Kang @Override 343c38d98f7bcd8effeb4921aeff6f6db8dfdba8de6Dongwon Kang public void onClick(View v) { 344c38d98f7bcd8effeb4921aeff6f6db8dfdba8de6Dongwon Kang dismiss(); 345c38d98f7bcd8effeb4921aeff6f6db8dfdba8de6Dongwon Kang } 346c38d98f7bcd8effeb4921aeff6f6db8dfdba8de6Dongwon Kang }); 347fa2e2acf79d791a90410025daad438968550d18cAlan Viverette mDialogAreaLayout = findViewById(R.id.mr_dialog_area); 348c38d98f7bcd8effeb4921aeff6f6db8dfdba8de6Dongwon Kang mDialogAreaLayout.setOnClickListener(new View.OnClickListener() { 349c38d98f7bcd8effeb4921aeff6f6db8dfdba8de6Dongwon Kang @Override 350c38d98f7bcd8effeb4921aeff6f6db8dfdba8de6Dongwon Kang public void onClick(View v) { 351c38d98f7bcd8effeb4921aeff6f6db8dfdba8de6Dongwon Kang // Eat unhandled touch events. 352c38d98f7bcd8effeb4921aeff6f6db8dfdba8de6Dongwon Kang } 353c38d98f7bcd8effeb4921aeff6f6db8dfdba8de6Dongwon Kang }); 3546f6fdaf79cd74810b2b96514c6914ae1dbe6c5f0Jae Seo int color = MediaRouterThemeHelper.getButtonTextColor(mContext); 355fa2e2acf79d791a90410025daad438968550d18cAlan Viverette mDisconnectButton = findViewById(BUTTON_DISCONNECT_RES_ID); 35606991009e52024cbb3dde550988e06149e77a269Jae Seo mDisconnectButton.setText(R.string.mr_controller_disconnect); 3576f6fdaf79cd74810b2b96514c6914ae1dbe6c5f0Jae Seo mDisconnectButton.setTextColor(color); 35894be6100218126ce6a08bf1f56209578500b361fRoboErik mDisconnectButton.setOnClickListener(listener); 35911417b1cfde8f1749905f2d735623af9214148afJeff Brown 360fa2e2acf79d791a90410025daad438968550d18cAlan Viverette mStopCastingButton = findViewById(BUTTON_STOP_RES_ID); 3616a39e73d20f14bed34f6bd9bc61b5b59d5050477Donghyun Cho mStopCastingButton.setText(R.string.mr_controller_stop_casting); 3626f6fdaf79cd74810b2b96514c6914ae1dbe6c5f0Jae Seo mStopCastingButton.setTextColor(color); 36394be6100218126ce6a08bf1f56209578500b361fRoboErik mStopCastingButton.setOnClickListener(listener); 36411417b1cfde8f1749905f2d735623af9214148afJeff Brown 365fa2e2acf79d791a90410025daad438968550d18cAlan Viverette mRouteNameTextView = findViewById(R.id.mr_name); 366fa2e2acf79d791a90410025daad438968550d18cAlan Viverette mCloseButton = findViewById(R.id.mr_close); 367b48ccf48b0281e69262fc643d0def898aede407bSungsoo Lim mCloseButton.setOnClickListener(listener); 368fa2e2acf79d791a90410025daad438968550d18cAlan Viverette mCustomControlLayout = findViewById(R.id.mr_custom_control); 369fa2e2acf79d791a90410025daad438968550d18cAlan Viverette mDefaultControlLayout = findViewById(R.id.mr_default_control); 370f291fbba316ca92573d84dbe37e48e9d83181318Jae Seo 371f291fbba316ca92573d84dbe37e48e9d83181318Jae Seo // Start the session activity when a content item (album art, title or subtitle) is clicked. 372f291fbba316ca92573d84dbe37e48e9d83181318Jae Seo View.OnClickListener onClickListener = new View.OnClickListener() { 373f291fbba316ca92573d84dbe37e48e9d83181318Jae Seo @Override 374f291fbba316ca92573d84dbe37e48e9d83181318Jae Seo public void onClick(View v) { 375f291fbba316ca92573d84dbe37e48e9d83181318Jae Seo if (mMediaController != null) { 376f291fbba316ca92573d84dbe37e48e9d83181318Jae Seo PendingIntent pi = mMediaController.getSessionActivity(); 377f291fbba316ca92573d84dbe37e48e9d83181318Jae Seo if (pi != null) { 378f291fbba316ca92573d84dbe37e48e9d83181318Jae Seo try { 379f291fbba316ca92573d84dbe37e48e9d83181318Jae Seo pi.send(); 380242b255caba1d6fdd651e32fffa68e0dbeb9b65bDongwon Kang dismiss(); 381f291fbba316ca92573d84dbe37e48e9d83181318Jae Seo } catch (PendingIntent.CanceledException e) { 382f291fbba316ca92573d84dbe37e48e9d83181318Jae Seo Log.e(TAG, pi + " was not sent, it had been canceled."); 383f291fbba316ca92573d84dbe37e48e9d83181318Jae Seo } 384f291fbba316ca92573d84dbe37e48e9d83181318Jae Seo } 385f291fbba316ca92573d84dbe37e48e9d83181318Jae Seo } 386f291fbba316ca92573d84dbe37e48e9d83181318Jae Seo } 387f291fbba316ca92573d84dbe37e48e9d83181318Jae Seo }; 388fa2e2acf79d791a90410025daad438968550d18cAlan Viverette mArtView = findViewById(R.id.mr_art); 389f291fbba316ca92573d84dbe37e48e9d83181318Jae Seo mArtView.setOnClickListener(onClickListener); 390f291fbba316ca92573d84dbe37e48e9d83181318Jae Seo findViewById(R.id.mr_control_title_container).setOnClickListener(onClickListener); 3916051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo 392fa2e2acf79d791a90410025daad438968550d18cAlan Viverette mMediaMainControlLayout = findViewById(R.id.mr_media_main_control); 3931ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mDividerView = findViewById(R.id.mr_control_divider); 3941ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim 395fa2e2acf79d791a90410025daad438968550d18cAlan Viverette mPlaybackControlLayout = findViewById(R.id.mr_playback_control); 396fa2e2acf79d791a90410025daad438968550d18cAlan Viverette mTitleView = findViewById(R.id.mr_control_title); 397fa2e2acf79d791a90410025daad438968550d18cAlan Viverette mSubtitleView = findViewById(R.id.mr_control_subtitle); 398fa2e2acf79d791a90410025daad438968550d18cAlan Viverette mPlaybackControlButton = findViewById(R.id.mr_control_playback_ctrl); 3996a39e73d20f14bed34f6bd9bc61b5b59d5050477Donghyun Cho mPlaybackControlButton.setOnClickListener(listener); 4001ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim 401fa2e2acf79d791a90410025daad438968550d18cAlan Viverette mVolumeControlLayout = findViewById(R.id.mr_volume_control); 402dbe6b4010999eaa31c5bbac520277391717c2ef0Sungsoo Lim mVolumeControlLayout.setVisibility(View.GONE); 403fa2e2acf79d791a90410025daad438968550d18cAlan Viverette mVolumeSlider = findViewById(R.id.mr_volume_slider); 404dbe6b4010999eaa31c5bbac520277391717c2ef0Sungsoo Lim mVolumeSlider.setTag(mRoute); 405435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim mVolumeChangeListener = new VolumeChangeListener(); 406435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim mVolumeSlider.setOnSeekBarChangeListener(mVolumeChangeListener); 4071ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim 408fa2e2acf79d791a90410025daad438968550d18cAlan Viverette mVolumeGroupList = findViewById(R.id.mr_volume_group_list); 4092242344e6d1a2fe48c99926c39a87d1e0e4326cfDonghyun Cho mGroupMemberRoutes = new ArrayList<MediaRouter.RouteInfo>(); 410166da1fa21cc24216730da32c9b81c591349db87Donghyun Cho mVolumeGroupAdapter = new VolumeGroupAdapter(mVolumeGroupList.getContext(), 411166da1fa21cc24216730da32c9b81c591349db87Donghyun Cho mGroupMemberRoutes); 4122242344e6d1a2fe48c99926c39a87d1e0e4326cfDonghyun Cho mVolumeGroupList.setAdapter(mVolumeGroupAdapter); 4131c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho mGroupMemberRoutesAnimatingWithBitmap = new HashSet<>(); 4142242344e6d1a2fe48c99926c39a87d1e0e4326cfDonghyun Cho 415d807ca0f601dc0b9807e0ed635b3f502fddec083Jae Seo MediaRouterThemeHelper.setMediaControlsBackgroundColor(mContext, 416d807ca0f601dc0b9807e0ed635b3f502fddec083Jae Seo mMediaMainControlLayout, mVolumeGroupList, getGroup() != null); 417d807ca0f601dc0b9807e0ed635b3f502fddec083Jae Seo MediaRouterThemeHelper.setVolumeSliderColor(mContext, 418d807ca0f601dc0b9807e0ed635b3f502fddec083Jae Seo (MediaRouteVolumeSlider) mVolumeSlider, mMediaMainControlLayout); 419dbe6b4010999eaa31c5bbac520277391717c2ef0Sungsoo Lim mVolumeSliderMap = new HashMap<>(); 420dbe6b4010999eaa31c5bbac520277391717c2ef0Sungsoo Lim mVolumeSliderMap.put(mRoute, mVolumeSlider); 421d807ca0f601dc0b9807e0ed635b3f502fddec083Jae Seo 422328f1006c17ddeb3eb563580bcd6638e1cfb4320Jaewan Kim mGroupExpandCollapseButton = 423fa2e2acf79d791a90410025daad438968550d18cAlan Viverette findViewById(R.id.mr_group_expand_collapse); 4241ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mGroupExpandCollapseButton.setOnClickListener(new View.OnClickListener() { 4251ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim @Override 4261ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim public void onClick(View v) { 4272b274bd3e06bd33c9b2a0851256afcda94d96395Dongwon Kang mIsGroupExpanded = !mIsGroupExpanded; 4282b274bd3e06bd33c9b2a0851256afcda94d96395Dongwon Kang if (mIsGroupExpanded) { 4291ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mVolumeGroupList.setVisibility(View.VISIBLE); 4301ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim } 4311c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho loadInterpolator(); 4321c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho updateLayoutHeight(true); 4331ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim } 4341ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim }); 4351c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho loadInterpolator(); 4364c5deffa8ddeb34accfded51e2be8573fbc1f301Dongwon Kang mGroupListAnimationDurationMs = mContext.getResources().getInteger( 437c38d98f7bcd8effeb4921aeff6f6db8dfdba8de6Dongwon Kang R.integer.mr_controller_volume_group_list_animation_duration_ms); 4381c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho mGroupListFadeInDurationMs = mContext.getResources().getInteger( 4391c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho R.integer.mr_controller_volume_group_list_fade_in_duration_ms); 4401c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho mGroupListFadeOutDurationMs = mContext.getResources().getInteger( 4411c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho R.integer.mr_controller_volume_group_list_fade_out_duration_ms); 44211417b1cfde8f1749905f2d735623af9214148afJeff Brown 4437ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim mCustomControlView = onCreateMediaControlView(savedInstanceState); 4447ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim if (mCustomControlView != null) { 4451ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mCustomControlLayout.addView(mCustomControlView); 4461ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mCustomControlLayout.setVisibility(View.VISIBLE); 44711417b1cfde8f1749905f2d735623af9214148afJeff Brown } 44886a802c8d09983d8725cccf59217e65d3e0c6373Jae Seo mCreated = true; 449d52e30f3736a821e45266c28c334756f5f7e55c3Jae Seo updateLayout(); 450d52e30f3736a821e45266c28c334756f5f7e55c3Jae Seo } 451d52e30f3736a821e45266c28c334756f5f7e55c3Jae Seo 452d52e30f3736a821e45266c28c334756f5f7e55c3Jae Seo /** 453d52e30f3736a821e45266c28c334756f5f7e55c3Jae Seo * Sets the width of the dialog. Also called when configuration changes. 454d52e30f3736a821e45266c28c334756f5f7e55c3Jae Seo */ 455d52e30f3736a821e45266c28c334756f5f7e55c3Jae Seo void updateLayout() { 4564c5deffa8ddeb34accfded51e2be8573fbc1f301Dongwon Kang int width = MediaRouteDialogHelper.getDialogWidth(mContext); 457d52e30f3736a821e45266c28c334756f5f7e55c3Jae Seo getWindow().setLayout(width, ViewGroup.LayoutParams.WRAP_CONTENT); 458d52e30f3736a821e45266c28c334756f5f7e55c3Jae Seo 459d52e30f3736a821e45266c28c334756f5f7e55c3Jae Seo View decorView = getWindow().getDecorView(); 460d52e30f3736a821e45266c28c334756f5f7e55c3Jae Seo mDialogContentWidth = width - decorView.getPaddingLeft() - decorView.getPaddingRight(); 461d52e30f3736a821e45266c28c334756f5f7e55c3Jae Seo 4624c5deffa8ddeb34accfded51e2be8573fbc1f301Dongwon Kang Resources res = mContext.getResources(); 463c5738b858579021cc89fffd8a891b4c5ea8c0f83Jaewan Kim mVolumeGroupListItemIconSize = res.getDimensionPixelSize( 464c5738b858579021cc89fffd8a891b4c5ea8c0f83Jaewan Kim R.dimen.mr_controller_volume_group_list_item_icon_size); 465c5738b858579021cc89fffd8a891b4c5ea8c0f83Jaewan Kim mVolumeGroupListItemHeight = res.getDimensionPixelSize( 466c5738b858579021cc89fffd8a891b4c5ea8c0f83Jaewan Kim R.dimen.mr_controller_volume_group_list_item_height); 467c5738b858579021cc89fffd8a891b4c5ea8c0f83Jaewan Kim mVolumeGroupListMaxHeight = res.getDimensionPixelSize( 468c5738b858579021cc89fffd8a891b4c5ea8c0f83Jaewan Kim R.dimen.mr_controller_volume_group_list_max_height); 469c5738b858579021cc89fffd8a891b4c5ea8c0f83Jaewan Kim 47075322d1d57085c80a76d0d6db41426777dab08d0Donghyun Cho // Fetch art icons again for layout changes to resize it accordingly 471c74ed2dfd8328da1f1786f1e4fb07f0e8eebd35bJae Seo mArtIconBitmap = null; 472c74ed2dfd8328da1f1786f1e4fb07f0e8eebd35bJae Seo mArtIconUri = null; 47375322d1d57085c80a76d0d6db41426777dab08d0Donghyun Cho updateArtIconIfNeeded(); 4741c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho update(false); 47511417b1cfde8f1749905f2d735623af9214148afJeff Brown } 47611417b1cfde8f1749905f2d735623af9214148afJeff Brown 47711417b1cfde8f1749905f2d735623af9214148afJeff Brown @Override 47811417b1cfde8f1749905f2d735623af9214148afJeff Brown public void onAttachedToWindow() { 47911417b1cfde8f1749905f2d735623af9214148afJeff Brown super.onAttachedToWindow(); 480e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mAttachedToWindow = true; 48111417b1cfde8f1749905f2d735623af9214148afJeff Brown 48211417b1cfde8f1749905f2d735623af9214148afJeff Brown mRouter.addCallback(MediaRouteSelector.EMPTY, mCallback, 48311417b1cfde8f1749905f2d735623af9214148afJeff Brown MediaRouter.CALLBACK_FLAG_UNFILTERED_EVENTS); 484e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik setMediaSession(mRouter.getMediaSessionToken()); 48511417b1cfde8f1749905f2d735623af9214148afJeff Brown } 48611417b1cfde8f1749905f2d735623af9214148afJeff Brown 48711417b1cfde8f1749905f2d735623af9214148afJeff Brown @Override 48811417b1cfde8f1749905f2d735623af9214148afJeff Brown public void onDetachedFromWindow() { 48911417b1cfde8f1749905f2d735623af9214148afJeff Brown mRouter.removeCallback(mCallback); 490e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik setMediaSession(null); 491e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mAttachedToWindow = false; 49211417b1cfde8f1749905f2d735623af9214148afJeff Brown super.onDetachedFromWindow(); 49311417b1cfde8f1749905f2d735623af9214148afJeff Brown } 49411417b1cfde8f1749905f2d735623af9214148afJeff Brown 49511417b1cfde8f1749905f2d735623af9214148afJeff Brown @Override 49611417b1cfde8f1749905f2d735623af9214148afJeff Brown public boolean onKeyDown(int keyCode, KeyEvent event) { 497ce8cbd614a64f94e54b936d66ecd14b6c1282ddfJeff Brown if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN 498ce8cbd614a64f94e54b936d66ecd14b6c1282ddfJeff Brown || keyCode == KeyEvent.KEYCODE_VOLUME_UP) { 499ce8cbd614a64f94e54b936d66ecd14b6c1282ddfJeff Brown mRoute.requestUpdateVolume(keyCode == KeyEvent.KEYCODE_VOLUME_DOWN ? -1 : 1); 500ce8cbd614a64f94e54b936d66ecd14b6c1282ddfJeff Brown return true; 50111417b1cfde8f1749905f2d735623af9214148afJeff Brown } 50211417b1cfde8f1749905f2d735623af9214148afJeff Brown return super.onKeyDown(keyCode, event); 50311417b1cfde8f1749905f2d735623af9214148afJeff Brown } 50411417b1cfde8f1749905f2d735623af9214148afJeff Brown 50511417b1cfde8f1749905f2d735623af9214148afJeff Brown @Override 50611417b1cfde8f1749905f2d735623af9214148afJeff Brown public boolean onKeyUp(int keyCode, KeyEvent event) { 507ce8cbd614a64f94e54b936d66ecd14b6c1282ddfJeff Brown if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN 508ce8cbd614a64f94e54b936d66ecd14b6c1282ddfJeff Brown || keyCode == KeyEvent.KEYCODE_VOLUME_UP) { 509ce8cbd614a64f94e54b936d66ecd14b6c1282ddfJeff Brown return true; 51011417b1cfde8f1749905f2d735623af9214148afJeff Brown } 51111417b1cfde8f1749905f2d735623af9214148afJeff Brown return super.onKeyUp(keyCode, event); 51211417b1cfde8f1749905f2d735623af9214148afJeff Brown } 51311417b1cfde8f1749905f2d735623af9214148afJeff Brown 514e2c6a94b6e4aab502f9b88dd3ff664bd90b25839Aurimas Liutikas void update(boolean animate) { 515d50585ab0e5ccd0ae70a55652deb7bcb3c2d3c56Donghyun Cho // Defer dialog updates if a user is adjusting a volume in the list 516d50585ab0e5ccd0ae70a55652deb7bcb3c2d3c56Donghyun Cho if (mRouteInVolumeSliderTouched != null) { 517d50585ab0e5ccd0ae70a55652deb7bcb3c2d3c56Donghyun Cho mHasPendingUpdate = true; 518d50585ab0e5ccd0ae70a55652deb7bcb3c2d3c56Donghyun Cho mPendingUpdateAnimationNeeded |= animate; 519d50585ab0e5ccd0ae70a55652deb7bcb3c2d3c56Donghyun Cho return; 520d50585ab0e5ccd0ae70a55652deb7bcb3c2d3c56Donghyun Cho } 521d50585ab0e5ccd0ae70a55652deb7bcb3c2d3c56Donghyun Cho mHasPendingUpdate = false; 522d50585ab0e5ccd0ae70a55652deb7bcb3c2d3c56Donghyun Cho mPendingUpdateAnimationNeeded = false; 523fa19abbe11335366feb6c885f8d75504ab8fe4f9Insun Kang if (!mRoute.isSelected() || mRoute.isDefaultOrBluetooth()) { 52411417b1cfde8f1749905f2d735623af9214148afJeff Brown dismiss(); 5257ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim return; 52611417b1cfde8f1749905f2d735623af9214148afJeff Brown } 52794be6100218126ce6a08bf1f56209578500b361fRoboErik if (!mCreated) { 5287ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim return; 52994be6100218126ce6a08bf1f56209578500b361fRoboErik } 5302ef36d857302c5cd738c7c8bdec53d31feebebbaJeff Brown 5317ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim mRouteNameTextView.setText(mRoute.getName()); 53206991009e52024cbb3dde550988e06149e77a269Jae Seo mDisconnectButton.setVisibility(mRoute.canDisconnect() ? View.VISIBLE : View.GONE); 533d50585ab0e5ccd0ae70a55652deb7bcb3c2d3c56Donghyun Cho if (mCustomControlView == null && mArtIconIsLoaded) { 5347108a5f54fd0db0639a140d320f5d4e85975ac23Donghyun Cho if (isBitmapRecycled(mArtIconLoadedBitmap)) { 5357108a5f54fd0db0639a140d320f5d4e85975ac23Donghyun Cho Log.w(TAG, "Can't set artwork image with recycled bitmap: " + mArtIconLoadedBitmap); 5367108a5f54fd0db0639a140d320f5d4e85975ac23Donghyun Cho } else { 5377108a5f54fd0db0639a140d320f5d4e85975ac23Donghyun Cho mArtView.setImageBitmap(mArtIconLoadedBitmap); 5387108a5f54fd0db0639a140d320f5d4e85975ac23Donghyun Cho mArtView.setBackgroundColor(mArtIconBackgroundColor); 5397108a5f54fd0db0639a140d320f5d4e85975ac23Donghyun Cho } 540d50585ab0e5ccd0ae70a55652deb7bcb3c2d3c56Donghyun Cho clearLoadedBitmap(); 541d50585ab0e5ccd0ae70a55652deb7bcb3c2d3c56Donghyun Cho } 54270cae05dea9dc5bb23200e27d02fd0d9cf2d4b5bJae Seo updateVolumeControlLayout(); 54370cae05dea9dc5bb23200e27d02fd0d9cf2d4b5bJae Seo updatePlaybackControlLayout(); 5441c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho updateLayoutHeight(animate); 5451ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim } 5461ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim 5477108a5f54fd0db0639a140d320f5d4e85975ac23Donghyun Cho private boolean isBitmapRecycled(Bitmap bitmap) { 5487108a5f54fd0db0639a140d320f5d4e85975ac23Donghyun Cho return bitmap != null && bitmap.isRecycled(); 5497108a5f54fd0db0639a140d320f5d4e85975ac23Donghyun Cho } 5507108a5f54fd0db0639a140d320f5d4e85975ac23Donghyun Cho 55170cae05dea9dc5bb23200e27d02fd0d9cf2d4b5bJae Seo private boolean canShowPlaybackControlLayout() { 552eb51f617d95c9a88a6ba528b1ad756f7bb7e7640Jae Seo return mCustomControlView == null && (mDescription != null || mState != null); 553f043da1f3472ec6f7f4cfe59574aa036b4acdc61Insun Kang } 554f043da1f3472ec6f7f4cfe59574aa036b4acdc61Insun Kang 5553fbf2b99dc391c331c2a816e13222a700a1f6dd5Jaewan Kim /** 5563fbf2b99dc391c331c2a816e13222a700a1f6dd5Jaewan Kim * Returns the height of main media controller which includes playback control and master 5573fbf2b99dc391c331c2a816e13222a700a1f6dd5Jaewan Kim * volume control. 5583fbf2b99dc391c331c2a816e13222a700a1f6dd5Jaewan Kim */ 5592c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim private int getMainControllerHeight(boolean showPlaybackControl) { 5602c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim int height = 0; 56170cae05dea9dc5bb23200e27d02fd0d9cf2d4b5bJae Seo if (showPlaybackControl || mVolumeControlLayout.getVisibility() == View.VISIBLE) { 5622c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim height += mMediaMainControlLayout.getPaddingTop() 5632c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim + mMediaMainControlLayout.getPaddingBottom(); 5642c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim if (showPlaybackControl) { 56570cae05dea9dc5bb23200e27d02fd0d9cf2d4b5bJae Seo height += mPlaybackControlLayout.getMeasuredHeight(); 5662c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim } 56770cae05dea9dc5bb23200e27d02fd0d9cf2d4b5bJae Seo if (mVolumeControlLayout.getVisibility() == View.VISIBLE) { 56870cae05dea9dc5bb23200e27d02fd0d9cf2d4b5bJae Seo height += mVolumeControlLayout.getMeasuredHeight(); 5692c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim } 57070cae05dea9dc5bb23200e27d02fd0d9cf2d4b5bJae Seo if (showPlaybackControl && mVolumeControlLayout.getVisibility() == View.VISIBLE) { 5712c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim height += mDividerView.getMeasuredHeight(); 5722c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim } 5732c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim } 5742c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim return height; 5752c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim } 5762c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim 57770cae05dea9dc5bb23200e27d02fd0d9cf2d4b5bJae Seo private void updateMediaControlVisibility(boolean canShowPlaybackControlLayout) { 57892fa1536ded1a81a2b054a08d72b591a13293f99Dongwon Kang // TODO: Update the top and bottom padding of the control layout according to the display 57992fa1536ded1a81a2b054a08d72b591a13293f99Dongwon Kang // height. 58070cae05dea9dc5bb23200e27d02fd0d9cf2d4b5bJae Seo mDividerView.setVisibility((mVolumeControlLayout.getVisibility() == View.VISIBLE 58170cae05dea9dc5bb23200e27d02fd0d9cf2d4b5bJae Seo && canShowPlaybackControlLayout) ? View.VISIBLE : View.GONE); 58270cae05dea9dc5bb23200e27d02fd0d9cf2d4b5bJae Seo mMediaMainControlLayout.setVisibility((mVolumeControlLayout.getVisibility() == View.GONE 58370cae05dea9dc5bb23200e27d02fd0d9cf2d4b5bJae Seo && !canShowPlaybackControlLayout) ? View.GONE : View.VISIBLE); 58486dcb627078ea297c4337ed634fc3fe874e23897Jae Seo } 58586dcb627078ea297c4337ed634fc3fe874e23897Jae Seo 586e2c6a94b6e4aab502f9b88dd3ff664bd90b25839Aurimas Liutikas void updateLayoutHeight(final boolean animate) { 58786dcb627078ea297c4337ed634fc3fe874e23897Jae Seo // We need to defer the update until the first layout has occurred, as we don't yet know the 58886dcb627078ea297c4337ed634fc3fe874e23897Jae Seo // overall visible display size in which the window this view is attached to has been 58986dcb627078ea297c4337ed634fc3fe874e23897Jae Seo // positioned in. 5901c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho mDefaultControlLayout.requestLayout(); 59186dcb627078ea297c4337ed634fc3fe874e23897Jae Seo ViewTreeObserver observer = mDefaultControlLayout.getViewTreeObserver(); 59286dcb627078ea297c4337ed634fc3fe874e23897Jae Seo observer.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { 59386dcb627078ea297c4337ed634fc3fe874e23897Jae Seo @Override 59486dcb627078ea297c4337ed634fc3fe874e23897Jae Seo public void onGlobalLayout() { 59586dcb627078ea297c4337ed634fc3fe874e23897Jae Seo mDefaultControlLayout.getViewTreeObserver().removeGlobalOnLayoutListener(this); 5961c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho if (mIsGroupListAnimating) { 5971c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho mIsGroupListAnimationPending = true; 5981c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho } else { 5991c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho updateLayoutHeightInternal(animate); 6001c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho } 60186dcb627078ea297c4337ed634fc3fe874e23897Jae Seo } 60286dcb627078ea297c4337ed634fc3fe874e23897Jae Seo }); 60392fa1536ded1a81a2b054a08d72b591a13293f99Dongwon Kang } 60492fa1536ded1a81a2b054a08d72b591a13293f99Dongwon Kang 6053fbf2b99dc391c331c2a816e13222a700a1f6dd5Jaewan Kim /** 6063fbf2b99dc391c331c2a816e13222a700a1f6dd5Jaewan Kim * Updates the height of views and hide artwork or metadata if space is limited. 6073fbf2b99dc391c331c2a816e13222a700a1f6dd5Jaewan Kim */ 608e2c6a94b6e4aab502f9b88dd3ff664bd90b25839Aurimas Liutikas void updateLayoutHeightInternal(boolean animate) { 60904b31a042cb2c18ffe6ccfba7309f6b8222678cdDongwon Kang // Measure the size of widgets and get the height of main components. 610c38d98f7bcd8effeb4921aeff6f6db8dfdba8de6Dongwon Kang int oldHeight = getLayoutHeight(mMediaMainControlLayout); 611e12dfa03641ad9cf0ddf272675bbe7d1198adbfdAurimas Liutikas setLayoutHeight(mMediaMainControlLayout, ViewGroup.LayoutParams.MATCH_PARENT); 61270cae05dea9dc5bb23200e27d02fd0d9cf2d4b5bJae Seo updateMediaControlVisibility(canShowPlaybackControlLayout()); 6132c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim View decorView = getWindow().getDecorView(); 6142c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim decorView.measure( 6152c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim MeasureSpec.makeMeasureSpec(getWindow().getAttributes().width, MeasureSpec.EXACTLY), 6162c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim MeasureSpec.UNSPECIFIED); 617c38d98f7bcd8effeb4921aeff6f6db8dfdba8de6Dongwon Kang setLayoutHeight(mMediaMainControlLayout, oldHeight); 6182c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim int artViewHeight = 0; 619fdafcdb0e1c10c02e17085d35ae2861362809e95Dongwon Kang if (mCustomControlView == null && mArtView.getDrawable() instanceof BitmapDrawable) { 6202c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim Bitmap art = ((BitmapDrawable) mArtView.getDrawable()).getBitmap(); 6212c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim if (art != null) { 6222c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim artViewHeight = getDesiredArtHeight(art.getWidth(), art.getHeight()); 6232c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim mArtView.setScaleType(art.getWidth() >= art.getHeight() 6242c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim ? ImageView.ScaleType.FIT_XY : ImageView.ScaleType.FIT_CENTER); 6252c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim } 6262c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim } 62770cae05dea9dc5bb23200e27d02fd0d9cf2d4b5bJae Seo int mainControllerHeight = getMainControllerHeight(canShowPlaybackControlLayout()); 6282242344e6d1a2fe48c99926c39a87d1e0e4326cfDonghyun Cho int volumeGroupListCount = mGroupMemberRoutes.size(); 629c5738b858579021cc89fffd8a891b4c5ea8c0f83Jaewan Kim // Scale down volume group list items in landscape mode. 6301c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho int expandedGroupListHeight = getGroup() == null ? 0 : 6311c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho mVolumeGroupListItemHeight * getGroup().getRoutes().size(); 63204b31a042cb2c18ffe6ccfba7309f6b8222678cdDongwon Kang if (volumeGroupListCount > 0) { 63304b31a042cb2c18ffe6ccfba7309f6b8222678cdDongwon Kang expandedGroupListHeight += mVolumeGroupListPaddingTop; 63404b31a042cb2c18ffe6ccfba7309f6b8222678cdDongwon Kang } 63504b31a042cb2c18ffe6ccfba7309f6b8222678cdDongwon Kang expandedGroupListHeight = Math.min(expandedGroupListHeight, mVolumeGroupListMaxHeight); 63604b31a042cb2c18ffe6ccfba7309f6b8222678cdDongwon Kang int visibleGroupListHeight = mIsGroupExpanded ? expandedGroupListHeight : 0; 63719d268075834665bf62567b224dcd3549c92d3c3Jae Seo 6388367dca195f881c38fbaf69a5d533a6cca820471Jaewan Kim int desiredControlLayoutHeight = 63904b31a042cb2c18ffe6ccfba7309f6b8222678cdDongwon Kang Math.max(artViewHeight, visibleGroupListHeight) + mainControllerHeight; 6402c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim Rect visibleRect = new Rect(); 6412c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim decorView.getWindowVisibleDisplayFrame(visibleRect); 6422c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim // Height of non-control views in decor view. 6432c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim // This includes title bar, button bar, and dialog's vertical padding which should be 6442c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim // always shown. 645c38d98f7bcd8effeb4921aeff6f6db8dfdba8de6Dongwon Kang int nonControlViewHeight = mDialogAreaLayout.getMeasuredHeight() 6462c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim - mDefaultControlLayout.getMeasuredHeight(); 6472c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim // Maximum allowed height for controls to fit screen. 6482c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim int maximumControlViewHeight = visibleRect.height() - nonControlViewHeight; 6492c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim 65004b31a042cb2c18ffe6ccfba7309f6b8222678cdDongwon Kang // Show artwork if it fits the screen. 651fdafcdb0e1c10c02e17085d35ae2861362809e95Dongwon Kang if (mCustomControlView == null && artViewHeight > 0 652fdafcdb0e1c10c02e17085d35ae2861362809e95Dongwon Kang && desiredControlLayoutHeight <= maximumControlViewHeight) { 6532c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim mArtView.setVisibility(View.VISIBLE); 6542c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim setLayoutHeight(mArtView, artViewHeight); 6552c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim } else { 656c38d98f7bcd8effeb4921aeff6f6db8dfdba8de6Dongwon Kang if (getLayoutHeight(mVolumeGroupList) + mMediaMainControlLayout.getMeasuredHeight() 657c38d98f7bcd8effeb4921aeff6f6db8dfdba8de6Dongwon Kang >= mDefaultControlLayout.getMeasuredHeight()) { 658c38d98f7bcd8effeb4921aeff6f6db8dfdba8de6Dongwon Kang mArtView.setVisibility(View.GONE); 659c38d98f7bcd8effeb4921aeff6f6db8dfdba8de6Dongwon Kang } 6602c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim artViewHeight = 0; 66104b31a042cb2c18ffe6ccfba7309f6b8222678cdDongwon Kang desiredControlLayoutHeight = visibleGroupListHeight + mainControllerHeight; 6622c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim } 663c38d98f7bcd8effeb4921aeff6f6db8dfdba8de6Dongwon Kang // Show the playback control if it fits the screen. 66470cae05dea9dc5bb23200e27d02fd0d9cf2d4b5bJae Seo if (canShowPlaybackControlLayout() 665f043da1f3472ec6f7f4cfe59574aa036b4acdc61Insun Kang && desiredControlLayoutHeight <= maximumControlViewHeight) { 66670cae05dea9dc5bb23200e27d02fd0d9cf2d4b5bJae Seo mPlaybackControlLayout.setVisibility(View.VISIBLE); 6672c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim } else { 66870cae05dea9dc5bb23200e27d02fd0d9cf2d4b5bJae Seo mPlaybackControlLayout.setVisibility(View.GONE); 6692c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim } 67070cae05dea9dc5bb23200e27d02fd0d9cf2d4b5bJae Seo updateMediaControlVisibility(mPlaybackControlLayout.getVisibility() == View.VISIBLE); 6712c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim mainControllerHeight = getMainControllerHeight( 67270cae05dea9dc5bb23200e27d02fd0d9cf2d4b5bJae Seo mPlaybackControlLayout.getVisibility() == View.VISIBLE); 6738367dca195f881c38fbaf69a5d533a6cca820471Jaewan Kim desiredControlLayoutHeight = 67404b31a042cb2c18ffe6ccfba7309f6b8222678cdDongwon Kang Math.max(artViewHeight, visibleGroupListHeight) + mainControllerHeight; 6752c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim 6762c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim // Limit the volume group list height to fit the screen. 6778367dca195f881c38fbaf69a5d533a6cca820471Jaewan Kim if (desiredControlLayoutHeight > maximumControlViewHeight) { 67804b31a042cb2c18ffe6ccfba7309f6b8222678cdDongwon Kang visibleGroupListHeight -= (desiredControlLayoutHeight - maximumControlViewHeight); 6798367dca195f881c38fbaf69a5d533a6cca820471Jaewan Kim desiredControlLayoutHeight = maximumControlViewHeight; 6802c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim } 681c38d98f7bcd8effeb4921aeff6f6db8dfdba8de6Dongwon Kang // Update the layouts with the computed heights. 682c38d98f7bcd8effeb4921aeff6f6db8dfdba8de6Dongwon Kang mMediaMainControlLayout.clearAnimation(); 683c38d98f7bcd8effeb4921aeff6f6db8dfdba8de6Dongwon Kang mVolumeGroupList.clearAnimation(); 684c38d98f7bcd8effeb4921aeff6f6db8dfdba8de6Dongwon Kang mDefaultControlLayout.clearAnimation(); 6851c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho if (animate) { 686c38d98f7bcd8effeb4921aeff6f6db8dfdba8de6Dongwon Kang animateLayoutHeight(mMediaMainControlLayout, mainControllerHeight); 687c38d98f7bcd8effeb4921aeff6f6db8dfdba8de6Dongwon Kang animateLayoutHeight(mVolumeGroupList, visibleGroupListHeight); 688c38d98f7bcd8effeb4921aeff6f6db8dfdba8de6Dongwon Kang animateLayoutHeight(mDefaultControlLayout, desiredControlLayoutHeight); 68904b31a042cb2c18ffe6ccfba7309f6b8222678cdDongwon Kang } else { 690c38d98f7bcd8effeb4921aeff6f6db8dfdba8de6Dongwon Kang setLayoutHeight(mMediaMainControlLayout, mainControllerHeight); 69104b31a042cb2c18ffe6ccfba7309f6b8222678cdDongwon Kang setLayoutHeight(mVolumeGroupList, visibleGroupListHeight); 692c38d98f7bcd8effeb4921aeff6f6db8dfdba8de6Dongwon Kang setLayoutHeight(mDefaultControlLayout, desiredControlLayoutHeight); 69304b31a042cb2c18ffe6ccfba7309f6b8222678cdDongwon Kang } 694c38d98f7bcd8effeb4921aeff6f6db8dfdba8de6Dongwon Kang // Maximize the window size with a transparent layout in advance for smooth animation. 695c38d98f7bcd8effeb4921aeff6f6db8dfdba8de6Dongwon Kang setLayoutHeight(mExpandableAreaLayout, visibleRect.height()); 6961c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho rebuildVolumeGroupList(animate); 69704b31a042cb2c18ffe6ccfba7309f6b8222678cdDongwon Kang } 69804b31a042cb2c18ffe6ccfba7309f6b8222678cdDongwon Kang 699e2c6a94b6e4aab502f9b88dd3ff664bd90b25839Aurimas Liutikas void updateVolumeGroupItemHeight(View item) { 7001c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho LinearLayout container = (LinearLayout) item.findViewById(R.id.volume_item_container); 7011c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho setLayoutHeight(container, mVolumeGroupListItemHeight); 702d5500b7822bfca5997827ec4c1c058dcab969c60Jaewan Kim View icon = item.findViewById(R.id.mr_volume_item_icon); 703d5500b7822bfca5997827ec4c1c058dcab969c60Jaewan Kim ViewGroup.LayoutParams lp = icon.getLayoutParams(); 704d5500b7822bfca5997827ec4c1c058dcab969c60Jaewan Kim lp.width = mVolumeGroupListItemIconSize; 705d5500b7822bfca5997827ec4c1c058dcab969c60Jaewan Kim lp.height = mVolumeGroupListItemIconSize; 706d5500b7822bfca5997827ec4c1c058dcab969c60Jaewan Kim icon.setLayoutParams(lp); 707d5500b7822bfca5997827ec4c1c058dcab969c60Jaewan Kim } 708d5500b7822bfca5997827ec4c1c058dcab969c60Jaewan Kim 709c38d98f7bcd8effeb4921aeff6f6db8dfdba8de6Dongwon Kang private void animateLayoutHeight(final View view, int targetHeight) { 710c38d98f7bcd8effeb4921aeff6f6db8dfdba8de6Dongwon Kang final int startValue = getLayoutHeight(view); 711c38d98f7bcd8effeb4921aeff6f6db8dfdba8de6Dongwon Kang final int endValue = targetHeight; 712c38d98f7bcd8effeb4921aeff6f6db8dfdba8de6Dongwon Kang Animation anim = new Animation() { 713c38d98f7bcd8effeb4921aeff6f6db8dfdba8de6Dongwon Kang @Override 714c38d98f7bcd8effeb4921aeff6f6db8dfdba8de6Dongwon Kang protected void applyTransformation(float interpolatedTime, Transformation t) { 715c38d98f7bcd8effeb4921aeff6f6db8dfdba8de6Dongwon Kang int height = startValue - (int) ((startValue - endValue) * interpolatedTime); 716c38d98f7bcd8effeb4921aeff6f6db8dfdba8de6Dongwon Kang setLayoutHeight(view, height); 71704b31a042cb2c18ffe6ccfba7309f6b8222678cdDongwon Kang } 718c38d98f7bcd8effeb4921aeff6f6db8dfdba8de6Dongwon Kang }; 719c38d98f7bcd8effeb4921aeff6f6db8dfdba8de6Dongwon Kang anim.setDuration(mGroupListAnimationDurationMs); 720c38d98f7bcd8effeb4921aeff6f6db8dfdba8de6Dongwon Kang if (android.os.Build.VERSION.SDK_INT >= 21) { 7211c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho anim.setInterpolator(mInterpolator); 72204b31a042cb2c18ffe6ccfba7309f6b8222678cdDongwon Kang } 7231c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho view.startAnimation(anim); 7241c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho } 725af1dca4a0419eac5d9ff8ecb1c442aacd90d3034Dongwon Kang 726e2c6a94b6e4aab502f9b88dd3ff664bd90b25839Aurimas Liutikas void loadInterpolator() { 7271c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho if (android.os.Build.VERSION.SDK_INT >= 21) { 7281c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho mInterpolator = mIsGroupExpanded ? mLinearOutSlowInInterpolator 7291c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho : mFastOutSlowInInterpolator; 7301c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho } else { 7311c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho mInterpolator = mAccelerateDecelerateInterpolator; 732af1dca4a0419eac5d9ff8ecb1c442aacd90d3034Dongwon Kang } 7332c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim } 7342c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim 73570cae05dea9dc5bb23200e27d02fd0d9cf2d4b5bJae Seo private void updateVolumeControlLayout() { 736dbe6b4010999eaa31c5bbac520277391717c2ef0Sungsoo Lim if (isVolumeControlAvailable(mRoute)) { 737dbe6b4010999eaa31c5bbac520277391717c2ef0Sungsoo Lim if (mVolumeControlLayout.getVisibility() == View.GONE) { 73870cae05dea9dc5bb23200e27d02fd0d9cf2d4b5bJae Seo mVolumeControlLayout.setVisibility(View.VISIBLE); 7391ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mVolumeSlider.setMax(mRoute.getVolumeMax()); 7401ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mVolumeSlider.setProgress(mRoute.getVolume()); 7411c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho mGroupExpandCollapseButton.setVisibility(getGroup() == null ? View.GONE 7421c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho : View.VISIBLE); 7437447b1958129579090ee279caac7d703dba2ad28Sungsoo Lim } 744dbe6b4010999eaa31c5bbac520277391717c2ef0Sungsoo Lim } else { 745dbe6b4010999eaa31c5bbac520277391717c2ef0Sungsoo Lim mVolumeControlLayout.setVisibility(View.GONE); 7461ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim } 7471ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim } 7481ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim 7491c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho private void rebuildVolumeGroupList(boolean animate) { 7501c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho List<MediaRouter.RouteInfo> routes = getGroup() == null ? null : getGroup().getRoutes(); 7511c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho if (routes == null) { 7521c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho mGroupMemberRoutes.clear(); 7531c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho mVolumeGroupAdapter.notifyDataSetChanged(); 7541c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho } else if (MediaRouteDialogHelper.listUnorderedEquals(mGroupMemberRoutes, routes)) { 7551c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho mVolumeGroupAdapter.notifyDataSetChanged(); 7561c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho } else { 7571c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho HashMap<MediaRouter.RouteInfo, Rect> previousRouteBoundMap = animate 7581c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho ? MediaRouteDialogHelper.getItemBoundMap(mVolumeGroupList, mVolumeGroupAdapter) 7591c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho : null; 7601c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho HashMap<MediaRouter.RouteInfo, BitmapDrawable> previousRouteBitmapMap = animate 7611c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho ? MediaRouteDialogHelper.getItemBitmapMap(mContext, mVolumeGroupList, 7621c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho mVolumeGroupAdapter) : null; 7631c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho mGroupMemberRoutesAdded = 7641c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho MediaRouteDialogHelper.getItemsAdded(mGroupMemberRoutes, routes); 7651c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho mGroupMemberRoutesRemoved = MediaRouteDialogHelper.getItemsRemoved(mGroupMemberRoutes, 7661c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho routes); 7671c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho mGroupMemberRoutes.addAll(0, mGroupMemberRoutesAdded); 7681c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho mGroupMemberRoutes.removeAll(mGroupMemberRoutesRemoved); 7691c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho mVolumeGroupAdapter.notifyDataSetChanged(); 7701c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho if (animate && mIsGroupExpanded 7711c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho && mGroupMemberRoutesAdded.size() + mGroupMemberRoutesRemoved.size() > 0) { 7721c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho animateGroupListItems(previousRouteBoundMap, previousRouteBitmapMap); 7731c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho } else { 7741c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho mGroupMemberRoutesAdded = null; 7751c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho mGroupMemberRoutesRemoved = null; 7761c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho } 7771c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho } 7781c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho } 7791c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho 7801c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho private void animateGroupListItems(final Map<MediaRouter.RouteInfo, Rect> previousRouteBoundMap, 7811c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho final Map<MediaRouter.RouteInfo, BitmapDrawable> previousRouteBitmapMap) { 7821c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho mVolumeGroupList.setEnabled(false); 7831c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho mVolumeGroupList.requestLayout(); 7841c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho mIsGroupListAnimating = true; 7851c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho ViewTreeObserver observer = mVolumeGroupList.getViewTreeObserver(); 7861c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho observer.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { 7871c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho @Override 7881c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho public void onGlobalLayout() { 7891c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho mVolumeGroupList.getViewTreeObserver().removeGlobalOnLayoutListener(this); 7901c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho animateGroupListItemsInternal(previousRouteBoundMap, previousRouteBitmapMap); 7911c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho } 7921c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho }); 7931c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho } 7941c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho 795e2c6a94b6e4aab502f9b88dd3ff664bd90b25839Aurimas Liutikas void animateGroupListItemsInternal( 7961c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho Map<MediaRouter.RouteInfo, Rect> previousRouteBoundMap, 7971c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho Map<MediaRouter.RouteInfo, BitmapDrawable> previousRouteBitmapMap) { 7981c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho if (mGroupMemberRoutesAdded == null || mGroupMemberRoutesRemoved == null) { 7991c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho return; 8001c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho } 8011c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho int groupSizeDelta = mGroupMemberRoutesAdded.size() - mGroupMemberRoutesRemoved.size(); 8021c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho boolean listenerRegistered = false; 8031c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho Animation.AnimationListener listener = new Animation.AnimationListener() { 8041c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho @Override 8051c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho public void onAnimationStart(Animation animation) { 8061c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho mVolumeGroupList.startAnimationAll(); 8071c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho mVolumeGroupList.postDelayed(mGroupListFadeInAnimation, 8081c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho mGroupListAnimationDurationMs); 8091c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho } 8101c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho 8111c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho @Override 8121c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho public void onAnimationEnd(Animation animation) { } 8131c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho 8141c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho @Override 8151c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho public void onAnimationRepeat(Animation animation) { } 8161c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho }; 8171c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho 8181c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho // Animate visible items from previous positions to current positions except routes added 8191c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho // just before. Added routes will remain hidden until translate animation finishes. 8201c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho int first = mVolumeGroupList.getFirstVisiblePosition(); 8211c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho for (int i = 0; i < mVolumeGroupList.getChildCount(); ++i) { 8221c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho View view = mVolumeGroupList.getChildAt(i); 8231c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho int position = first + i; 8241c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho MediaRouter.RouteInfo route = mVolumeGroupAdapter.getItem(position); 8251c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho Rect previousBounds = previousRouteBoundMap.get(route); 8261c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho int currentTop = view.getTop(); 8271c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho int previousTop = previousBounds != null ? previousBounds.top 8281c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho : (currentTop + mVolumeGroupListItemHeight * groupSizeDelta); 8291c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho AnimationSet animSet = new AnimationSet(true); 8301c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho if (mGroupMemberRoutesAdded != null && mGroupMemberRoutesAdded.contains(route)) { 8311c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho previousTop = currentTop; 8321c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho Animation alphaAnim = new AlphaAnimation(0.0f, 0.0f); 8331c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho alphaAnim.setDuration(mGroupListFadeInDurationMs); 8341c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho animSet.addAnimation(alphaAnim); 8351c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho } 8361c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho Animation translationAnim = new TranslateAnimation(0, 0, previousTop - currentTop, 0); 8371c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho translationAnim.setDuration(mGroupListAnimationDurationMs); 8381c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho animSet.addAnimation(translationAnim); 8391c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho animSet.setFillAfter(true); 8401c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho animSet.setFillEnabled(true); 8411c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho animSet.setInterpolator(mInterpolator); 8421c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho if (!listenerRegistered) { 8431c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho listenerRegistered = true; 8441c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho animSet.setAnimationListener(listener); 8451c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho } 8461c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho view.clearAnimation(); 8471c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho view.startAnimation(animSet); 8481c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho previousRouteBoundMap.remove(route); 8491c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho previousRouteBitmapMap.remove(route); 8501c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho } 8511c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho 8521c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho // If a member route doesn't exist any longer, it can be either removed or moved out of the 8531c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho // ListView layout boundary. In this case, use the previously captured bitmaps for 8541c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho // animation. 8551c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho for (Map.Entry<MediaRouter.RouteInfo, BitmapDrawable> item 8561c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho : previousRouteBitmapMap.entrySet()) { 8571c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho final MediaRouter.RouteInfo route = item.getKey(); 8581c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho final BitmapDrawable bitmap = item.getValue(); 8591c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho final Rect bounds = previousRouteBoundMap.get(route); 860ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas OverlayListView.OverlayObject object = null; 8611c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho if (mGroupMemberRoutesRemoved.contains(route)) { 862ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas object = new OverlayListView.OverlayObject(bitmap, bounds).setAlphaAnimation(1.0f, 0.0f) 8631c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho .setDuration(mGroupListFadeOutDurationMs) 8641c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho .setInterpolator(mInterpolator); 8651c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho } else { 8661c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho int deltaY = groupSizeDelta * mVolumeGroupListItemHeight; 867ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas object = new OverlayListView.OverlayObject(bitmap, bounds).setTranslateYAnimation(deltaY) 8681c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho .setDuration(mGroupListAnimationDurationMs) 8691c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho .setInterpolator(mInterpolator) 870ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas .setAnimationEndListener(new OverlayListView.OverlayObject.OnAnimationEndListener() { 8711c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho @Override 8721c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho public void onAnimationEnd() { 8731c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho mGroupMemberRoutesAnimatingWithBitmap.remove(route); 8741c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho mVolumeGroupAdapter.notifyDataSetChanged(); 8751c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho } 8761c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho }); 8771c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho mGroupMemberRoutesAnimatingWithBitmap.add(route); 8781c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho } 8791c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho mVolumeGroupList.addOverlayObject(object); 8801c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho } 8811c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho } 8821c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho 883e2c6a94b6e4aab502f9b88dd3ff664bd90b25839Aurimas Liutikas void startGroupListFadeInAnimation() { 8841c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho clearGroupListAnimation(true); 8851c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho mVolumeGroupList.requestLayout(); 8861c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho ViewTreeObserver observer = mVolumeGroupList.getViewTreeObserver(); 8871c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho observer.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { 8881c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho @Override 8891c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho public void onGlobalLayout() { 8901c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho mVolumeGroupList.getViewTreeObserver().removeGlobalOnLayoutListener(this); 8911c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho startGroupListFadeInAnimationInternal(); 8921c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho } 8931c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho }); 8941c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho } 8951c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho 896e2c6a94b6e4aab502f9b88dd3ff664bd90b25839Aurimas Liutikas void startGroupListFadeInAnimationInternal() { 8971c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho if (mGroupMemberRoutesAdded != null && mGroupMemberRoutesAdded.size() != 0) { 8981c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho fadeInAddedRoutes(); 8991c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho } else { 9001c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho finishAnimation(true); 9011c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho } 9021c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho } 9031c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho 904e2c6a94b6e4aab502f9b88dd3ff664bd90b25839Aurimas Liutikas void finishAnimation(boolean animate) { 9051c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho mGroupMemberRoutesAdded = null; 9061c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho mGroupMemberRoutesRemoved = null; 9071c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho mIsGroupListAnimating = false; 9081c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho if (mIsGroupListAnimationPending) { 9091c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho mIsGroupListAnimationPending = false; 9101c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho updateLayoutHeight(animate); 9111c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho } 9121c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho mVolumeGroupList.setEnabled(true); 9131c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho } 9141c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho 9151c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho private void fadeInAddedRoutes() { 9161c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho Animation.AnimationListener listener = new Animation.AnimationListener() { 9171c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho @Override 9181c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho public void onAnimationStart(Animation animation) { } 9191c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho 9201c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho @Override 9211c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho public void onAnimationEnd(Animation animation) { 9221c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho finishAnimation(true); 9231c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho } 9241c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho 9251c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho @Override 9261c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho public void onAnimationRepeat(Animation animation) { } 9271c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho }; 9281c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho boolean listenerRegistered = false; 9291c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho int first = mVolumeGroupList.getFirstVisiblePosition(); 9301c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho for (int i = 0; i < mVolumeGroupList.getChildCount(); ++i) { 9311c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho View view = mVolumeGroupList.getChildAt(i); 9321c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho int position = first + i; 9331c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho MediaRouter.RouteInfo route = mVolumeGroupAdapter.getItem(position); 9341c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho if (mGroupMemberRoutesAdded.contains(route)) { 9351c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho Animation alphaAnim = new AlphaAnimation(0.0f, 1.0f); 9361c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho alphaAnim.setDuration(mGroupListFadeInDurationMs); 9371c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho alphaAnim.setFillEnabled(true); 9381c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho alphaAnim.setFillAfter(true); 9391c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho if (!listenerRegistered) { 9401c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho listenerRegistered = true; 9411c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho alphaAnim.setAnimationListener(listener); 9421c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho } 9431c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho view.clearAnimation(); 9441c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho view.startAnimation(alphaAnim); 9451c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho } 9461c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho } 9471c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho } 9481c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho 9491c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho void clearGroupListAnimation(boolean exceptAddedRoutes) { 9501c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho int first = mVolumeGroupList.getFirstVisiblePosition(); 9511c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho for (int i = 0; i < mVolumeGroupList.getChildCount(); ++i) { 9521c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho View view = mVolumeGroupList.getChildAt(i); 9531c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho int position = first + i; 9541c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho MediaRouter.RouteInfo route = mVolumeGroupAdapter.getItem(position); 9551c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho if (exceptAddedRoutes && mGroupMemberRoutesAdded != null 9561c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho && mGroupMemberRoutesAdded.contains(route)) { 9571c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho continue; 9581c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho } 9591c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho LinearLayout container = (LinearLayout) view.findViewById(R.id.volume_item_container); 9601c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho container.setVisibility(View.VISIBLE); 9611c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho AnimationSet animSet = new AnimationSet(true); 9621c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho Animation alphaAnim = new AlphaAnimation(1.0f, 1.0f); 9631c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho alphaAnim.setDuration(0); 9641c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho animSet.addAnimation(alphaAnim); 9651c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho Animation translationAnim = new TranslateAnimation(0, 0, 0, 0); 9661c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho translationAnim.setDuration(0); 9671c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho animSet.setFillAfter(true); 9681c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho animSet.setFillEnabled(true); 9691c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho view.clearAnimation(); 9701c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho view.startAnimation(animSet); 9711c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho } 9721c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho mVolumeGroupList.stopAnimationAll(); 9731c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho if (!exceptAddedRoutes) { 9741c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho finishAnimation(false); 9752242344e6d1a2fe48c99926c39a87d1e0e4326cfDonghyun Cho } 9762242344e6d1a2fe48c99926c39a87d1e0e4326cfDonghyun Cho } 9772242344e6d1a2fe48c99926c39a87d1e0e4326cfDonghyun Cho 97870cae05dea9dc5bb23200e27d02fd0d9cf2d4b5bJae Seo private void updatePlaybackControlLayout() { 97970cae05dea9dc5bb23200e27d02fd0d9cf2d4b5bJae Seo if (canShowPlaybackControlLayout()) { 9801ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim CharSequence title = mDescription == null ? null : mDescription.getTitle(); 9811ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim boolean hasTitle = !TextUtils.isEmpty(title); 9821ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim 9831ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim CharSequence subtitle = mDescription == null ? null : mDescription.getSubtitle(); 9841ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim boolean hasSubtitle = !TextUtils.isEmpty(subtitle); 9851ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim 9868fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang boolean showTitle = false; 9878fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang boolean showSubtitle = false; 9888fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang if (mRoute.getPresentationDisplayId() 9898fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang != MediaRouter.RouteInfo.PRESENTATION_DISPLAY_ID_NONE) { 9908fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang // The user is currently casting screen. 9918fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang mTitleView.setText(R.string.mr_controller_casting_screen); 9928fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang showTitle = true; 9938fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang } else if (mState == null || mState.getState() == PlaybackStateCompat.STATE_NONE) { 994eb51f617d95c9a88a6ba528b1ad756f7bb7e7640Jae Seo // Show "No media selected" as we don't yet know the playback state. 995fa19abbe11335366feb6c885f8d75504ab8fe4f9Insun Kang mTitleView.setText(R.string.mr_controller_no_media_selected); 996fa19abbe11335366feb6c885f8d75504ab8fe4f9Insun Kang showTitle = true; 9978fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang } else if (!hasTitle && !hasSubtitle) { 9988fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang mTitleView.setText(R.string.mr_controller_no_info_available); 9998fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang showTitle = true; 10001ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim } else { 10018fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang if (hasTitle) { 10028fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang mTitleView.setText(title); 10038fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang showTitle = true; 10048fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang } 10058fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang if (hasSubtitle) { 10068fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang mSubtitleView.setText(subtitle); 10078fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang showSubtitle = true; 10088fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang } 10091ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim } 10108fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang mTitleView.setVisibility(showTitle ? View.VISIBLE : View.GONE); 10118fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang mSubtitleView.setVisibility(showSubtitle ? View.VISIBLE : View.GONE); 10128fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang 10131ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim if (mState != null) { 10141ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim boolean isPlaying = mState.getState() == PlaybackStateCompat.STATE_BUFFERING 10151ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim || mState.getState() == PlaybackStateCompat.STATE_PLAYING; 10166a39e73d20f14bed34f6bd9bc61b5b59d5050477Donghyun Cho Context playbackControlButtonContext = mPlaybackControlButton.getContext(); 10176a39e73d20f14bed34f6bd9bc61b5b59d5050477Donghyun Cho boolean visible = true; 10186a39e73d20f14bed34f6bd9bc61b5b59d5050477Donghyun Cho int iconDrawableAttr = 0; 10196a39e73d20f14bed34f6bd9bc61b5b59d5050477Donghyun Cho int iconDescResId = 0; 10206a39e73d20f14bed34f6bd9bc61b5b59d5050477Donghyun Cho if (isPlaying && isPauseActionSupported()) { 10216a39e73d20f14bed34f6bd9bc61b5b59d5050477Donghyun Cho iconDrawableAttr = R.attr.mediaRoutePauseDrawable; 10226a39e73d20f14bed34f6bd9bc61b5b59d5050477Donghyun Cho iconDescResId = R.string.mr_controller_pause; 10236a39e73d20f14bed34f6bd9bc61b5b59d5050477Donghyun Cho } else if (isPlaying && isStopActionSupported()) { 10246a39e73d20f14bed34f6bd9bc61b5b59d5050477Donghyun Cho iconDrawableAttr = R.attr.mediaRouteStopDrawable; 10256a39e73d20f14bed34f6bd9bc61b5b59d5050477Donghyun Cho iconDescResId = R.string.mr_controller_stop; 10266a39e73d20f14bed34f6bd9bc61b5b59d5050477Donghyun Cho } else if (!isPlaying && isPlayActionSupported()) { 10276a39e73d20f14bed34f6bd9bc61b5b59d5050477Donghyun Cho iconDrawableAttr = R.attr.mediaRoutePlayDrawable; 10286a39e73d20f14bed34f6bd9bc61b5b59d5050477Donghyun Cho iconDescResId = R.string.mr_controller_play; 10291ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim } else { 10306a39e73d20f14bed34f6bd9bc61b5b59d5050477Donghyun Cho visible = false; 10316a39e73d20f14bed34f6bd9bc61b5b59d5050477Donghyun Cho } 10326a39e73d20f14bed34f6bd9bc61b5b59d5050477Donghyun Cho mPlaybackControlButton.setVisibility(visible ? View.VISIBLE : View.GONE); 10336a39e73d20f14bed34f6bd9bc61b5b59d5050477Donghyun Cho if (visible) { 10346a39e73d20f14bed34f6bd9bc61b5b59d5050477Donghyun Cho mPlaybackControlButton.setImageResource( 10356a39e73d20f14bed34f6bd9bc61b5b59d5050477Donghyun Cho MediaRouterThemeHelper.getThemeResource( 10366a39e73d20f14bed34f6bd9bc61b5b59d5050477Donghyun Cho playbackControlButtonContext, iconDrawableAttr)); 10376a39e73d20f14bed34f6bd9bc61b5b59d5050477Donghyun Cho mPlaybackControlButton.setContentDescription( 10386a39e73d20f14bed34f6bd9bc61b5b59d5050477Donghyun Cho playbackControlButtonContext.getResources() 10396a39e73d20f14bed34f6bd9bc61b5b59d5050477Donghyun Cho .getText(iconDescResId)); 10401ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim } 10411ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim } 10421ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim } 10432b274bd3e06bd33c9b2a0851256afcda94d96395Dongwon Kang } 10442b274bd3e06bd33c9b2a0851256afcda94d96395Dongwon Kang 10456a39e73d20f14bed34f6bd9bc61b5b59d5050477Donghyun Cho private boolean isPlayActionSupported() { 10466a39e73d20f14bed34f6bd9bc61b5b59d5050477Donghyun Cho return (mState.getActions() & (ACTION_PLAY | ACTION_PLAY_PAUSE)) != 0; 10476a39e73d20f14bed34f6bd9bc61b5b59d5050477Donghyun Cho } 10486a39e73d20f14bed34f6bd9bc61b5b59d5050477Donghyun Cho 10496a39e73d20f14bed34f6bd9bc61b5b59d5050477Donghyun Cho private boolean isPauseActionSupported() { 10506a39e73d20f14bed34f6bd9bc61b5b59d5050477Donghyun Cho return (mState.getActions() & (ACTION_PAUSE | ACTION_PLAY_PAUSE)) != 0; 10516a39e73d20f14bed34f6bd9bc61b5b59d5050477Donghyun Cho } 10526a39e73d20f14bed34f6bd9bc61b5b59d5050477Donghyun Cho 10536a39e73d20f14bed34f6bd9bc61b5b59d5050477Donghyun Cho private boolean isStopActionSupported() { 10546a39e73d20f14bed34f6bd9bc61b5b59d5050477Donghyun Cho return (mState.getActions() & ACTION_STOP) != 0; 10556a39e73d20f14bed34f6bd9bc61b5b59d5050477Donghyun Cho } 10566a39e73d20f14bed34f6bd9bc61b5b59d5050477Donghyun Cho 1057e2c6a94b6e4aab502f9b88dd3ff664bd90b25839Aurimas Liutikas boolean isVolumeControlAvailable(MediaRouter.RouteInfo route) { 10587447b1958129579090ee279caac7d703dba2ad28Sungsoo Lim return mVolumeControlEnabled && route.getVolumeHandling() 10597447b1958129579090ee279caac7d703dba2ad28Sungsoo Lim == MediaRouter.RouteInfo.PLAYBACK_VOLUME_VARIABLE; 1060f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah } 1061f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah 106204b31a042cb2c18ffe6ccfba7309f6b8222678cdDongwon Kang private static int getLayoutHeight(View view) { 106304b31a042cb2c18ffe6ccfba7309f6b8222678cdDongwon Kang return view.getLayoutParams().height; 106404b31a042cb2c18ffe6ccfba7309f6b8222678cdDongwon Kang } 106504b31a042cb2c18ffe6ccfba7309f6b8222678cdDongwon Kang 1066e2c6a94b6e4aab502f9b88dd3ff664bd90b25839Aurimas Liutikas static void setLayoutHeight(View view, int height) { 1067be6358a7c928a09f2c767524299f86a8aad84558Dongwon Kang ViewGroup.LayoutParams lp = view.getLayoutParams(); 1068be6358a7c928a09f2c767524299f86a8aad84558Dongwon Kang lp.height = height; 1069be6358a7c928a09f2c767524299f86a8aad84558Dongwon Kang view.setLayoutParams(lp); 1070be6358a7c928a09f2c767524299f86a8aad84558Dongwon Kang } 1071be6358a7c928a09f2c767524299f86a8aad84558Dongwon Kang 1072376f4d5a03a3dfc9d4ca30074b3df3e424bd7e4bDonghyun Cho private static boolean uriEquals(Uri uri1, Uri uri2) { 1073376f4d5a03a3dfc9d4ca30074b3df3e424bd7e4bDonghyun Cho if (uri1 != null && uri1.equals(uri2)) { 1074376f4d5a03a3dfc9d4ca30074b3df3e424bd7e4bDonghyun Cho return true; 1075376f4d5a03a3dfc9d4ca30074b3df3e424bd7e4bDonghyun Cho } else if (uri1 == null && uri2 == null) { 1076376f4d5a03a3dfc9d4ca30074b3df3e424bd7e4bDonghyun Cho return true; 1077376f4d5a03a3dfc9d4ca30074b3df3e424bd7e4bDonghyun Cho } 1078376f4d5a03a3dfc9d4ca30074b3df3e424bd7e4bDonghyun Cho return false; 1079376f4d5a03a3dfc9d4ca30074b3df3e424bd7e4bDonghyun Cho } 1080376f4d5a03a3dfc9d4ca30074b3df3e424bd7e4bDonghyun Cho 108113d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim /** 108213d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim * Returns desired art height to fit into controller dialog. 108313d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim */ 1084e2c6a94b6e4aab502f9b88dd3ff664bd90b25839Aurimas Liutikas int getDesiredArtHeight(int originalWidth, int originalHeight) { 108513d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim if (originalWidth >= originalHeight) { 108613d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim // For landscape art, fit width to dialog width. 1087f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seo return (int) ((float) mDialogContentWidth * originalHeight / originalWidth + 0.5f); 108813d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim } 108913d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim // For portrait art, fit height to 16:9 ratio case's height. 1090f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seo return (int) ((float) mDialogContentWidth * 9 / 16 + 0.5f); 109113d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim } 109213d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim 1093e2c6a94b6e4aab502f9b88dd3ff664bd90b25839Aurimas Liutikas void updateArtIconIfNeeded() { 109475322d1d57085c80a76d0d6db41426777dab08d0Donghyun Cho if (mCustomControlView != null || !isIconChanged()) { 109575322d1d57085c80a76d0d6db41426777dab08d0Donghyun Cho return; 109675322d1d57085c80a76d0d6db41426777dab08d0Donghyun Cho } 109775322d1d57085c80a76d0d6db41426777dab08d0Donghyun Cho if (mFetchArtTask != null) { 109875322d1d57085c80a76d0d6db41426777dab08d0Donghyun Cho mFetchArtTask.cancel(true); 109975322d1d57085c80a76d0d6db41426777dab08d0Donghyun Cho } 110075322d1d57085c80a76d0d6db41426777dab08d0Donghyun Cho mFetchArtTask = new FetchArtTask(); 110175322d1d57085c80a76d0d6db41426777dab08d0Donghyun Cho mFetchArtTask.execute(); 110275322d1d57085c80a76d0d6db41426777dab08d0Donghyun Cho } 110375322d1d57085c80a76d0d6db41426777dab08d0Donghyun Cho 110475322d1d57085c80a76d0d6db41426777dab08d0Donghyun Cho /** 1105d50585ab0e5ccd0ae70a55652deb7bcb3c2d3c56Donghyun Cho * Clear the bitmap loaded by FetchArtTask. Will be called after the loaded bitmaps are applied 1106d50585ab0e5ccd0ae70a55652deb7bcb3c2d3c56Donghyun Cho * to artwork, or no longer valid. 1107d50585ab0e5ccd0ae70a55652deb7bcb3c2d3c56Donghyun Cho */ 1108e2c6a94b6e4aab502f9b88dd3ff664bd90b25839Aurimas Liutikas void clearLoadedBitmap() { 1109d50585ab0e5ccd0ae70a55652deb7bcb3c2d3c56Donghyun Cho mArtIconIsLoaded = false; 1110d50585ab0e5ccd0ae70a55652deb7bcb3c2d3c56Donghyun Cho mArtIconLoadedBitmap = null; 1111d50585ab0e5ccd0ae70a55652deb7bcb3c2d3c56Donghyun Cho mArtIconBackgroundColor = 0; 1112d50585ab0e5ccd0ae70a55652deb7bcb3c2d3c56Donghyun Cho } 1113d50585ab0e5ccd0ae70a55652deb7bcb3c2d3c56Donghyun Cho 1114d50585ab0e5ccd0ae70a55652deb7bcb3c2d3c56Donghyun Cho /** 111575322d1d57085c80a76d0d6db41426777dab08d0Donghyun Cho * Returns whether a new art image is different from an original art image. Compares 111675322d1d57085c80a76d0d6db41426777dab08d0Donghyun Cho * Bitmap objects first, and then compares URIs only if bitmap is unchanged with 111775322d1d57085c80a76d0d6db41426777dab08d0Donghyun Cho * a null value. 111875322d1d57085c80a76d0d6db41426777dab08d0Donghyun Cho */ 111975322d1d57085c80a76d0d6db41426777dab08d0Donghyun Cho private boolean isIconChanged() { 112075322d1d57085c80a76d0d6db41426777dab08d0Donghyun Cho Bitmap newBitmap = mDescription == null ? null : mDescription.getIconBitmap(); 112175322d1d57085c80a76d0d6db41426777dab08d0Donghyun Cho Uri newUri = mDescription == null ? null : mDescription.getIconUri(); 112275322d1d57085c80a76d0d6db41426777dab08d0Donghyun Cho Bitmap oldBitmap = mFetchArtTask == null ? mArtIconBitmap : mFetchArtTask.getIconBitmap(); 112375322d1d57085c80a76d0d6db41426777dab08d0Donghyun Cho Uri oldUri = mFetchArtTask == null ? mArtIconUri : mFetchArtTask.getIconUri(); 112475322d1d57085c80a76d0d6db41426777dab08d0Donghyun Cho if (oldBitmap != newBitmap) { 112575322d1d57085c80a76d0d6db41426777dab08d0Donghyun Cho return true; 112675322d1d57085c80a76d0d6db41426777dab08d0Donghyun Cho } else if (oldBitmap == null && !uriEquals(oldUri, newUri)) { 112775322d1d57085c80a76d0d6db41426777dab08d0Donghyun Cho return true; 112875322d1d57085c80a76d0d6db41426777dab08d0Donghyun Cho } 112975322d1d57085c80a76d0d6db41426777dab08d0Donghyun Cho return false; 113075322d1d57085c80a76d0d6db41426777dab08d0Donghyun Cho } 113175322d1d57085c80a76d0d6db41426777dab08d0Donghyun Cho 113211417b1cfde8f1749905f2d735623af9214148afJeff Brown private final class MediaRouterCallback extends MediaRouter.Callback { 1133e2c6a94b6e4aab502f9b88dd3ff664bd90b25839Aurimas Liutikas MediaRouterCallback() { 1134e2c6a94b6e4aab502f9b88dd3ff664bd90b25839Aurimas Liutikas } 1135e2c6a94b6e4aab502f9b88dd3ff664bd90b25839Aurimas Liutikas 113611417b1cfde8f1749905f2d735623af9214148afJeff Brown @Override 113711417b1cfde8f1749905f2d735623af9214148afJeff Brown public void onRouteUnselected(MediaRouter router, MediaRouter.RouteInfo route) { 11381c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho update(false); 113911417b1cfde8f1749905f2d735623af9214148afJeff Brown } 114011417b1cfde8f1749905f2d735623af9214148afJeff Brown 114111417b1cfde8f1749905f2d735623af9214148afJeff Brown @Override 114211417b1cfde8f1749905f2d735623af9214148afJeff Brown public void onRouteChanged(MediaRouter router, MediaRouter.RouteInfo route) { 11431c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho update(true); 114411417b1cfde8f1749905f2d735623af9214148afJeff Brown } 114511417b1cfde8f1749905f2d735623af9214148afJeff Brown 114611417b1cfde8f1749905f2d735623af9214148afJeff Brown @Override 114711417b1cfde8f1749905f2d735623af9214148afJeff Brown public void onRouteVolumeChanged(MediaRouter router, MediaRouter.RouteInfo route) { 1148dbe6b4010999eaa31c5bbac520277391717c2ef0Sungsoo Lim SeekBar volumeSlider = mVolumeSliderMap.get(route); 1149ddec4bb519422d680d93911e95d252b620d09ba2Insun Kang int volume = route.getVolume(); 1150ddec4bb519422d680d93911e95d252b620d09ba2Insun Kang if (DEBUG) { 1151ddec4bb519422d680d93911e95d252b620d09ba2Insun Kang Log.d(TAG, "onRouteVolumeChanged(), route.getVolume:" + volume); 1152ddec4bb519422d680d93911e95d252b620d09ba2Insun Kang } 1153dbe6b4010999eaa31c5bbac520277391717c2ef0Sungsoo Lim if (volumeSlider != null && mRouteInVolumeSliderTouched != route) { 1154ddec4bb519422d680d93911e95d252b620d09ba2Insun Kang volumeSlider.setProgress(volume); 115594be6100218126ce6a08bf1f56209578500b361fRoboErik } 115694be6100218126ce6a08bf1f56209578500b361fRoboErik } 115794be6100218126ce6a08bf1f56209578500b361fRoboErik } 115894be6100218126ce6a08bf1f56209578500b361fRoboErik 115994be6100218126ce6a08bf1f56209578500b361fRoboErik private final class MediaControllerCallback extends MediaControllerCompat.Callback { 1160e2c6a94b6e4aab502f9b88dd3ff664bd90b25839Aurimas Liutikas MediaControllerCallback() { 1161e2c6a94b6e4aab502f9b88dd3ff664bd90b25839Aurimas Liutikas } 1162e2c6a94b6e4aab502f9b88dd3ff664bd90b25839Aurimas Liutikas 116394be6100218126ce6a08bf1f56209578500b361fRoboErik @Override 116494be6100218126ce6a08bf1f56209578500b361fRoboErik public void onSessionDestroyed() { 116594be6100218126ce6a08bf1f56209578500b361fRoboErik if (mMediaController != null) { 116694be6100218126ce6a08bf1f56209578500b361fRoboErik mMediaController.unregisterCallback(mControllerCallback); 116794be6100218126ce6a08bf1f56209578500b361fRoboErik mMediaController = null; 116894be6100218126ce6a08bf1f56209578500b361fRoboErik } 116994be6100218126ce6a08bf1f56209578500b361fRoboErik } 117094be6100218126ce6a08bf1f56209578500b361fRoboErik 117194be6100218126ce6a08bf1f56209578500b361fRoboErik @Override 117294be6100218126ce6a08bf1f56209578500b361fRoboErik public void onPlaybackStateChanged(PlaybackStateCompat state) { 117394be6100218126ce6a08bf1f56209578500b361fRoboErik mState = state; 11741c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho update(false); 117594be6100218126ce6a08bf1f56209578500b361fRoboErik } 117694be6100218126ce6a08bf1f56209578500b361fRoboErik 117794be6100218126ce6a08bf1f56209578500b361fRoboErik @Override 117894be6100218126ce6a08bf1f56209578500b361fRoboErik public void onMetadataChanged(MediaMetadataCompat metadata) { 117994be6100218126ce6a08bf1f56209578500b361fRoboErik mDescription = metadata == null ? null : metadata.getDescription(); 118075322d1d57085c80a76d0d6db41426777dab08d0Donghyun Cho updateArtIconIfNeeded(); 11811c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho update(false); 118294be6100218126ce6a08bf1f56209578500b361fRoboErik } 118394be6100218126ce6a08bf1f56209578500b361fRoboErik } 118494be6100218126ce6a08bf1f56209578500b361fRoboErik 118594be6100218126ce6a08bf1f56209578500b361fRoboErik private final class ClickListener implements View.OnClickListener { 1186e2c6a94b6e4aab502f9b88dd3ff664bd90b25839Aurimas Liutikas ClickListener() { 1187e2c6a94b6e4aab502f9b88dd3ff664bd90b25839Aurimas Liutikas } 1188e2c6a94b6e4aab502f9b88dd3ff664bd90b25839Aurimas Liutikas 118994be6100218126ce6a08bf1f56209578500b361fRoboErik @Override 119094be6100218126ce6a08bf1f56209578500b361fRoboErik public void onClick(View v) { 119194be6100218126ce6a08bf1f56209578500b361fRoboErik int id = v.getId(); 119206991009e52024cbb3dde550988e06149e77a269Jae Seo if (id == BUTTON_STOP_RES_ID || id == BUTTON_DISCONNECT_RES_ID) { 119394be6100218126ce6a08bf1f56209578500b361fRoboErik if (mRoute.isSelected()) { 119406991009e52024cbb3dde550988e06149e77a269Jae Seo mRouter.unselect(id == BUTTON_STOP_RES_ID ? 119594be6100218126ce6a08bf1f56209578500b361fRoboErik MediaRouter.UNSELECT_REASON_STOPPED : 119694be6100218126ce6a08bf1f56209578500b361fRoboErik MediaRouter.UNSELECT_REASON_DISCONNECTED); 119794be6100218126ce6a08bf1f56209578500b361fRoboErik } 119894be6100218126ce6a08bf1f56209578500b361fRoboErik dismiss(); 11996a39e73d20f14bed34f6bd9bc61b5b59d5050477Donghyun Cho } else if (id == R.id.mr_control_playback_ctrl) { 120094be6100218126ce6a08bf1f56209578500b361fRoboErik if (mMediaController != null && mState != null) { 1201ee7ae661b02471fe598566b1e90adbacda240b0bJae Seo boolean isPlaying = mState.getState() == PlaybackStateCompat.STATE_PLAYING; 12026a39e73d20f14bed34f6bd9bc61b5b59d5050477Donghyun Cho int actionDescResId = 0; 12036a39e73d20f14bed34f6bd9bc61b5b59d5050477Donghyun Cho if (isPlaying && isPauseActionSupported()) { 120494be6100218126ce6a08bf1f56209578500b361fRoboErik mMediaController.getTransportControls().pause(); 12056a39e73d20f14bed34f6bd9bc61b5b59d5050477Donghyun Cho actionDescResId = R.string.mr_controller_pause; 12066a39e73d20f14bed34f6bd9bc61b5b59d5050477Donghyun Cho } else if (isPlaying && isStopActionSupported()) { 12076a39e73d20f14bed34f6bd9bc61b5b59d5050477Donghyun Cho mMediaController.getTransportControls().stop(); 12086a39e73d20f14bed34f6bd9bc61b5b59d5050477Donghyun Cho actionDescResId = R.string.mr_controller_stop; 12096a39e73d20f14bed34f6bd9bc61b5b59d5050477Donghyun Cho } else if (!isPlaying && isPlayActionSupported()){ 121094be6100218126ce6a08bf1f56209578500b361fRoboErik mMediaController.getTransportControls().play(); 12116a39e73d20f14bed34f6bd9bc61b5b59d5050477Donghyun Cho actionDescResId = R.string.mr_controller_play; 121294be6100218126ce6a08bf1f56209578500b361fRoboErik } 1213ee7ae661b02471fe598566b1e90adbacda240b0bJae Seo // Announce the action for accessibility. 12146a39e73d20f14bed34f6bd9bc61b5b59d5050477Donghyun Cho if (mAccessibilityManager != null && mAccessibilityManager.isEnabled() 12156a39e73d20f14bed34f6bd9bc61b5b59d5050477Donghyun Cho && actionDescResId != 0) { 1216ee7ae661b02471fe598566b1e90adbacda240b0bJae Seo AccessibilityEvent event = AccessibilityEvent.obtain( 1217ee7ae661b02471fe598566b1e90adbacda240b0bJae Seo AccessibilityEventCompat.TYPE_ANNOUNCEMENT); 12184c5deffa8ddeb34accfded51e2be8573fbc1f301Dongwon Kang event.setPackageName(mContext.getPackageName()); 1219ee7ae661b02471fe598566b1e90adbacda240b0bJae Seo event.setClassName(getClass().getName()); 12206a39e73d20f14bed34f6bd9bc61b5b59d5050477Donghyun Cho event.getText().add(mContext.getString(actionDescResId)); 1221ee7ae661b02471fe598566b1e90adbacda240b0bJae Seo mAccessibilityManager.sendAccessibilityEvent(event); 1222ee7ae661b02471fe598566b1e90adbacda240b0bJae Seo } 122394be6100218126ce6a08bf1f56209578500b361fRoboErik } 12241ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim } else if (id == R.id.mr_close) { 1225b48ccf48b0281e69262fc643d0def898aede407bSungsoo Lim dismiss(); 122611417b1cfde8f1749905f2d735623af9214148afJeff Brown } 122711417b1cfde8f1749905f2d735623af9214148afJeff Brown } 122811417b1cfde8f1749905f2d735623af9214148afJeff Brown } 1229005482649154d0970693b3967241eb4d2cb22003Jaewan Kim 1230dbe6b4010999eaa31c5bbac520277391717c2ef0Sungsoo Lim private class VolumeChangeListener implements SeekBar.OnSeekBarChangeListener { 1231435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim private final Runnable mStopTrackingTouch = new Runnable() { 12326051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo @Override 1233435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim public void run() { 1234dbe6b4010999eaa31c5bbac520277391717c2ef0Sungsoo Lim if (mRouteInVolumeSliderTouched != null) { 1235dbe6b4010999eaa31c5bbac520277391717c2ef0Sungsoo Lim mRouteInVolumeSliderTouched = null; 1236d50585ab0e5ccd0ae70a55652deb7bcb3c2d3c56Donghyun Cho if (mHasPendingUpdate) { 1237d50585ab0e5ccd0ae70a55652deb7bcb3c2d3c56Donghyun Cho update(mPendingUpdateAnimationNeeded); 1238d50585ab0e5ccd0ae70a55652deb7bcb3c2d3c56Donghyun Cho } 12396051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo } 12406051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo } 1241435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim }; 12426051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo 1243e2c6a94b6e4aab502f9b88dd3ff664bd90b25839Aurimas Liutikas VolumeChangeListener() { 1244e2c6a94b6e4aab502f9b88dd3ff664bd90b25839Aurimas Liutikas } 1245e2c6a94b6e4aab502f9b88dd3ff664bd90b25839Aurimas Liutikas 1246435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim @Override 1247435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim public void onStartTrackingTouch(SeekBar seekBar) { 1248dbe6b4010999eaa31c5bbac520277391717c2ef0Sungsoo Lim if (mRouteInVolumeSliderTouched != null) { 1249435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim mVolumeSlider.removeCallbacks(mStopTrackingTouch); 12506051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo } 1251dbe6b4010999eaa31c5bbac520277391717c2ef0Sungsoo Lim mRouteInVolumeSliderTouched = (MediaRouter.RouteInfo) seekBar.getTag(); 1252435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim } 12536051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo 1254435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim @Override 1255435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim public void onStopTrackingTouch(SeekBar seekBar) { 1256435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim // Defer resetting mVolumeSliderTouched to allow the media route provider 1257435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim // a little time to settle into its new state and publish the final 1258435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim // volume update. 1259435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim mVolumeSlider.postDelayed(mStopTrackingTouch, VOLUME_UPDATE_DELAY_MILLIS); 1260435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim } 1261435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim 1262435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim @Override 1263435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { 1264435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim if (fromUser) { 1265dbe6b4010999eaa31c5bbac520277391717c2ef0Sungsoo Lim MediaRouter.RouteInfo route = (MediaRouter.RouteInfo) seekBar.getTag(); 1266ddec4bb519422d680d93911e95d252b620d09ba2Insun Kang if (DEBUG) { 1267ddec4bb519422d680d93911e95d252b620d09ba2Insun Kang Log.d(TAG, "onProgressChanged(): calling " 1268ddec4bb519422d680d93911e95d252b620d09ba2Insun Kang + "MediaRouter.RouteInfo.requestSetVolume(" + progress + ")"); 1269435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim } 1270ddec4bb519422d680d93911e95d252b620d09ba2Insun Kang route.requestSetVolume(progress); 12716051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo } 1272435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim } 1273435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim } 1274435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim 1275435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim private class VolumeGroupAdapter extends ArrayAdapter<MediaRouter.RouteInfo> { 1276d807ca0f601dc0b9807e0ed635b3f502fddec083Jae Seo final float mDisabledAlpha; 12776051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo 12786051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo public VolumeGroupAdapter(Context context, List<MediaRouter.RouteInfo> objects) { 12796051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo super(context, 0, objects); 1280d807ca0f601dc0b9807e0ed635b3f502fddec083Jae Seo mDisabledAlpha = MediaRouterThemeHelper.getDisabledAlpha(context); 12816051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo } 12826051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo 12836051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo @Override 12843b2841ba851902b0516ed8a2178a0d92c0a8b923Hyundo Moon public boolean isEnabled(int position) { 12853b2841ba851902b0516ed8a2178a0d92c0a8b923Hyundo Moon return false; 12863b2841ba851902b0516ed8a2178a0d92c0a8b923Hyundo Moon } 12873b2841ba851902b0516ed8a2178a0d92c0a8b923Hyundo Moon 12883b2841ba851902b0516ed8a2178a0d92c0a8b923Hyundo Moon @Override 12896051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo public View getView(final int position, View convertView, ViewGroup parent) { 12906051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo View v = convertView; 12916051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo if (v == null) { 1292166da1fa21cc24216730da32c9b81c591349db87Donghyun Cho v = LayoutInflater.from(parent.getContext()).inflate( 12932c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim R.layout.mr_controller_volume_item, parent, false); 1294d5500b7822bfca5997827ec4c1c058dcab969c60Jaewan Kim } else { 1295d5500b7822bfca5997827ec4c1c058dcab969c60Jaewan Kim updateVolumeGroupItemHeight(v); 12966051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo } 129719d268075834665bf62567b224dcd3549c92d3c3Jae Seo 12986051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo MediaRouter.RouteInfo route = getItem(position); 12996051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo if (route != null) { 13000e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo boolean isEnabled = route.isEnabled(); 13010e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo 13027ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim TextView routeName = (TextView) v.findViewById(R.id.mr_name); 13030e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo routeName.setEnabled(isEnabled); 13040e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo routeName.setText(route.getName()); 13056051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo 1306ea15dd5d0313d55452f552d8583eb230b2c9506fJaewan Kim MediaRouteVolumeSlider volumeSlider = 1307ea15dd5d0313d55452f552d8583eb230b2c9506fJaewan Kim (MediaRouteVolumeSlider) v.findViewById(R.id.mr_volume_slider); 1308d807ca0f601dc0b9807e0ed635b3f502fddec083Jae Seo MediaRouterThemeHelper.setVolumeSliderColor( 1309166da1fa21cc24216730da32c9b81c591349db87Donghyun Cho parent.getContext(), volumeSlider, mVolumeGroupList); 1310dbe6b4010999eaa31c5bbac520277391717c2ef0Sungsoo Lim volumeSlider.setTag(route); 1311dbe6b4010999eaa31c5bbac520277391717c2ef0Sungsoo Lim mVolumeSliderMap.put(route, volumeSlider); 13120b72510d7bc402b71065e069852d10a8592d55deJaewan Kim volumeSlider.setHideThumb(!isEnabled); 1313d807ca0f601dc0b9807e0ed635b3f502fddec083Jae Seo volumeSlider.setEnabled(isEnabled); 13140e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo if (isEnabled) { 13157447b1958129579090ee279caac7d703dba2ad28Sungsoo Lim if (isVolumeControlAvailable(route)) { 13160e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo volumeSlider.setMax(route.getVolumeMax()); 13170e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo volumeSlider.setProgress(route.getVolume()); 1318435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim volumeSlider.setOnSeekBarChangeListener(mVolumeChangeListener); 13190e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo } else { 13200e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo volumeSlider.setMax(100); 13210e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo volumeSlider.setProgress(100); 13220e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo volumeSlider.setEnabled(false); 13230e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo } 13240e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo } 13250e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo 13260e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo ImageView volumeItemIcon = 13277ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim (ImageView) v.findViewById(R.id.mr_volume_item_icon); 1328d807ca0f601dc0b9807e0ed635b3f502fddec083Jae Seo volumeItemIcon.setAlpha(isEnabled ? 0xFF : (int) (0xFF * mDisabledAlpha)); 13291c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho 13301c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho // If overlay bitmap exists, real view should remain hidden until 13311c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho // the animation ends. 13321c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho LinearLayout container = (LinearLayout) v.findViewById(R.id.volume_item_container); 13331c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho container.setVisibility(mGroupMemberRoutesAnimatingWithBitmap.contains(route) 13341c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho ? View.INVISIBLE : View.VISIBLE); 13351c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho 13361c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho // Routes which are being added will be invisible until animation ends. 13371c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho if (mGroupMemberRoutesAdded != null && mGroupMemberRoutesAdded.contains(route)) { 13381c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho Animation alphaAnim = new AlphaAnimation(0.0f, 0.0f); 13391c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho alphaAnim.setDuration(0); 13401c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho alphaAnim.setFillEnabled(true); 13411c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho alphaAnim.setFillAfter(true); 13421c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho v.clearAnimation(); 13431c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho v.startAnimation(alphaAnim); 13441c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho } 13456051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo } 13466051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo return v; 13476051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo } 13486051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo } 13496051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo 1350005482649154d0970693b3967241eb4d2cb22003Jaewan Kim private class FetchArtTask extends AsyncTask<Void, Void, Bitmap> { 135187654ffe5c675519fd2a611c8fad40ee0979011eDonghyun Cho // Show animation only when fetching takes a long time. 135287654ffe5c675519fd2a611c8fad40ee0979011eDonghyun Cho private static final long SHOW_ANIM_TIME_THRESHOLD_MILLIS = 120L; 135387654ffe5c675519fd2a611c8fad40ee0979011eDonghyun Cho 135487654ffe5c675519fd2a611c8fad40ee0979011eDonghyun Cho private final Bitmap mIconBitmap; 135587654ffe5c675519fd2a611c8fad40ee0979011eDonghyun Cho private final Uri mIconUri; 135687654ffe5c675519fd2a611c8fad40ee0979011eDonghyun Cho private int mBackgroundColor; 135787654ffe5c675519fd2a611c8fad40ee0979011eDonghyun Cho private long mStartTimeMillis; 13588bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo 13598bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo FetchArtTask() { 13607108a5f54fd0db0639a140d320f5d4e85975ac23Donghyun Cho Bitmap bitmap = mDescription == null ? null : mDescription.getIconBitmap(); 13617108a5f54fd0db0639a140d320f5d4e85975ac23Donghyun Cho if (isBitmapRecycled(bitmap)) { 13627108a5f54fd0db0639a140d320f5d4e85975ac23Donghyun Cho Log.w(TAG, "Can't fetch the given art bitmap because it's already recycled."); 13637108a5f54fd0db0639a140d320f5d4e85975ac23Donghyun Cho bitmap = null; 13647108a5f54fd0db0639a140d320f5d4e85975ac23Donghyun Cho } 13657108a5f54fd0db0639a140d320f5d4e85975ac23Donghyun Cho mIconBitmap = bitmap; 13668bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo mIconUri = mDescription == null ? null : mDescription.getIconUri(); 13678bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo } 13688bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo 136975322d1d57085c80a76d0d6db41426777dab08d0Donghyun Cho public Bitmap getIconBitmap() { 137075322d1d57085c80a76d0d6db41426777dab08d0Donghyun Cho return mIconBitmap; 137175322d1d57085c80a76d0d6db41426777dab08d0Donghyun Cho } 137275322d1d57085c80a76d0d6db41426777dab08d0Donghyun Cho 137375322d1d57085c80a76d0d6db41426777dab08d0Donghyun Cho public Uri getIconUri() { 137475322d1d57085c80a76d0d6db41426777dab08d0Donghyun Cho return mIconUri; 137575322d1d57085c80a76d0d6db41426777dab08d0Donghyun Cho } 137675322d1d57085c80a76d0d6db41426777dab08d0Donghyun Cho 13778bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo @Override 13788bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo protected void onPreExecute() { 137987654ffe5c675519fd2a611c8fad40ee0979011eDonghyun Cho mStartTimeMillis = SystemClock.uptimeMillis(); 1380d50585ab0e5ccd0ae70a55652deb7bcb3c2d3c56Donghyun Cho clearLoadedBitmap(); 13818bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo } 1382005482649154d0970693b3967241eb4d2cb22003Jaewan Kim 1383005482649154d0970693b3967241eb4d2cb22003Jaewan Kim @Override 1384005482649154d0970693b3967241eb4d2cb22003Jaewan Kim protected Bitmap doInBackground(Void... arg) { 138513d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim Bitmap art = null; 13868bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo if (mIconBitmap != null) { 13878bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo art = mIconBitmap; 13888bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo } else if (mIconUri != null) { 1389376f4d5a03a3dfc9d4ca30074b3df3e424bd7e4bDonghyun Cho InputStream stream = null; 1390005482649154d0970693b3967241eb4d2cb22003Jaewan Kim try { 1391376f4d5a03a3dfc9d4ca30074b3df3e424bd7e4bDonghyun Cho if ((stream = openInputStreamByScheme(mIconUri)) == null) { 1392376f4d5a03a3dfc9d4ca30074b3df3e424bd7e4bDonghyun Cho Log.w(TAG, "Unable to open: " + mIconUri); 1393376f4d5a03a3dfc9d4ca30074b3df3e424bd7e4bDonghyun Cho return null; 1394376f4d5a03a3dfc9d4ca30074b3df3e424bd7e4bDonghyun Cho } 139513d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim // Query art size. 1396005482649154d0970693b3967241eb4d2cb22003Jaewan Kim BitmapFactory.Options options = new BitmapFactory.Options(); 1397005482649154d0970693b3967241eb4d2cb22003Jaewan Kim options.inJustDecodeBounds = true; 1398005482649154d0970693b3967241eb4d2cb22003Jaewan Kim BitmapFactory.decodeStream(stream, null, options); 139913d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim if (options.outWidth == 0 || options.outHeight == 0) { 140013d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim return null; 140113d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim } 140213d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim // Rewind the stream in order to restart art decoding. 1403005482649154d0970693b3967241eb4d2cb22003Jaewan Kim try { 1404005482649154d0970693b3967241eb4d2cb22003Jaewan Kim stream.reset(); 1405005482649154d0970693b3967241eb4d2cb22003Jaewan Kim } catch (IOException e) { 1406005482649154d0970693b3967241eb4d2cb22003Jaewan Kim // Failed to rewind the stream, try to reopen it. 1407005482649154d0970693b3967241eb4d2cb22003Jaewan Kim stream.close(); 1408376f4d5a03a3dfc9d4ca30074b3df3e424bd7e4bDonghyun Cho if ((stream = openInputStreamByScheme(mIconUri)) == null) { 1409376f4d5a03a3dfc9d4ca30074b3df3e424bd7e4bDonghyun Cho Log.w(TAG, "Unable to open: " + mIconUri); 1410376f4d5a03a3dfc9d4ca30074b3df3e424bd7e4bDonghyun Cho return null; 1411376f4d5a03a3dfc9d4ca30074b3df3e424bd7e4bDonghyun Cho } 1412005482649154d0970693b3967241eb4d2cb22003Jaewan Kim } 141313d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim // Calculate required size to decode the art and possibly resize it. 1414005482649154d0970693b3967241eb4d2cb22003Jaewan Kim options.inJustDecodeBounds = false; 141513d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim int reqHeight = getDesiredArtHeight(options.outWidth, options.outHeight); 141613d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim int ratio = options.outHeight / reqHeight; 1417005482649154d0970693b3967241eb4d2cb22003Jaewan Kim options.inSampleSize = Math.max(1, Integer.highestOneBit(ratio)); 1418005482649154d0970693b3967241eb4d2cb22003Jaewan Kim if (isCancelled()) { 1419005482649154d0970693b3967241eb4d2cb22003Jaewan Kim return null; 1420005482649154d0970693b3967241eb4d2cb22003Jaewan Kim } 142113d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim art = BitmapFactory.decodeStream(stream, null, options); 1422005482649154d0970693b3967241eb4d2cb22003Jaewan Kim } catch (IOException e){ 14238bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo Log.w(TAG, "Unable to open: " + mIconUri, e); 1424005482649154d0970693b3967241eb4d2cb22003Jaewan Kim } finally { 1425005482649154d0970693b3967241eb4d2cb22003Jaewan Kim if (stream != null) { 1426005482649154d0970693b3967241eb4d2cb22003Jaewan Kim try { 1427005482649154d0970693b3967241eb4d2cb22003Jaewan Kim stream.close(); 1428005482649154d0970693b3967241eb4d2cb22003Jaewan Kim } catch (IOException e) { 1429005482649154d0970693b3967241eb4d2cb22003Jaewan Kim } 1430005482649154d0970693b3967241eb4d2cb22003Jaewan Kim } 1431005482649154d0970693b3967241eb4d2cb22003Jaewan Kim } 1432005482649154d0970693b3967241eb4d2cb22003Jaewan Kim } 14337108a5f54fd0db0639a140d320f5d4e85975ac23Donghyun Cho if (isBitmapRecycled(art)) { 14347108a5f54fd0db0639a140d320f5d4e85975ac23Donghyun Cho Log.w(TAG, "Can't use recycled bitmap: " + art); 14357108a5f54fd0db0639a140d320f5d4e85975ac23Donghyun Cho return null; 14367108a5f54fd0db0639a140d320f5d4e85975ac23Donghyun Cho } 1437145e93b13dd025b278665494e7be0c15b8df5986Jaewan Kim if (art != null && art.getWidth() < art.getHeight()) { 1438c4c371f91673a882177f16fa95723e7e69f54882Insun Kang // Portrait art requires dominant color as background color. 1439145e93b13dd025b278665494e7be0c15b8df5986Jaewan Kim Palette palette = new Palette.Builder(art).maximumColorCount(1).generate(); 1440be6358a7c928a09f2c767524299f86a8aad84558Dongwon Kang mBackgroundColor = palette.getSwatches().isEmpty() 1441145e93b13dd025b278665494e7be0c15b8df5986Jaewan Kim ? 0 : palette.getSwatches().get(0).getRgb(); 1442005482649154d0970693b3967241eb4d2cb22003Jaewan Kim } 144313d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim return art; 1444005482649154d0970693b3967241eb4d2cb22003Jaewan Kim } 1445005482649154d0970693b3967241eb4d2cb22003Jaewan Kim 1446005482649154d0970693b3967241eb4d2cb22003Jaewan Kim @Override 144713d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim protected void onPostExecute(Bitmap art) { 1448005482649154d0970693b3967241eb4d2cb22003Jaewan Kim mFetchArtTask = null; 1449c9bbadfa70a2a3f92bd497bf1ed6f7586f758ce6Alan Viverette if (!ObjectsCompat.equals(mArtIconBitmap, mIconBitmap) 1450c9bbadfa70a2a3f92bd497bf1ed6f7586f758ce6Alan Viverette || !ObjectsCompat.equals(mArtIconUri, mIconUri)) { 14518bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo mArtIconBitmap = mIconBitmap; 1452d50585ab0e5ccd0ae70a55652deb7bcb3c2d3c56Donghyun Cho mArtIconLoadedBitmap = art; 14538bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo mArtIconUri = mIconUri; 1454d50585ab0e5ccd0ae70a55652deb7bcb3c2d3c56Donghyun Cho mArtIconBackgroundColor = mBackgroundColor; 1455d50585ab0e5ccd0ae70a55652deb7bcb3c2d3c56Donghyun Cho mArtIconIsLoaded = true; 145687654ffe5c675519fd2a611c8fad40ee0979011eDonghyun Cho long elapsedTimeMillis = SystemClock.uptimeMillis() - mStartTimeMillis; 1457d50585ab0e5ccd0ae70a55652deb7bcb3c2d3c56Donghyun Cho // Loaded bitmap will be applied on the next update 1458d50585ab0e5ccd0ae70a55652deb7bcb3c2d3c56Donghyun Cho update(elapsedTimeMillis > SHOW_ANIM_TIME_THRESHOLD_MILLIS); 14598bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo } 1460005482649154d0970693b3967241eb4d2cb22003Jaewan Kim } 1461376f4d5a03a3dfc9d4ca30074b3df3e424bd7e4bDonghyun Cho 1462376f4d5a03a3dfc9d4ca30074b3df3e424bd7e4bDonghyun Cho private InputStream openInputStreamByScheme(Uri uri) throws IOException { 1463376f4d5a03a3dfc9d4ca30074b3df3e424bd7e4bDonghyun Cho String scheme = uri.getScheme().toLowerCase(); 1464376f4d5a03a3dfc9d4ca30074b3df3e424bd7e4bDonghyun Cho InputStream stream = null; 1465376f4d5a03a3dfc9d4ca30074b3df3e424bd7e4bDonghyun Cho if (ContentResolver.SCHEME_ANDROID_RESOURCE.equals(scheme) 1466376f4d5a03a3dfc9d4ca30074b3df3e424bd7e4bDonghyun Cho || ContentResolver.SCHEME_CONTENT.equals(scheme) 1467376f4d5a03a3dfc9d4ca30074b3df3e424bd7e4bDonghyun Cho || ContentResolver.SCHEME_FILE.equals(scheme)) { 1468376f4d5a03a3dfc9d4ca30074b3df3e424bd7e4bDonghyun Cho stream = mContext.getContentResolver().openInputStream(uri); 1469376f4d5a03a3dfc9d4ca30074b3df3e424bd7e4bDonghyun Cho } else { 1470376f4d5a03a3dfc9d4ca30074b3df3e424bd7e4bDonghyun Cho URL url = new URL(uri.toString()); 1471376f4d5a03a3dfc9d4ca30074b3df3e424bd7e4bDonghyun Cho URLConnection conn = url.openConnection(); 1472376f4d5a03a3dfc9d4ca30074b3df3e424bd7e4bDonghyun Cho conn.setConnectTimeout(CONNECTION_TIMEOUT_MILLIS); 1473376f4d5a03a3dfc9d4ca30074b3df3e424bd7e4bDonghyun Cho conn.setReadTimeout(CONNECTION_TIMEOUT_MILLIS); 1474376f4d5a03a3dfc9d4ca30074b3df3e424bd7e4bDonghyun Cho stream = conn.getInputStream(); 1475376f4d5a03a3dfc9d4ca30074b3df3e424bd7e4bDonghyun Cho } 1476376f4d5a03a3dfc9d4ca30074b3df3e424bd7e4bDonghyun Cho return (stream == null) ? null : new BufferedInputStream(stream); 1477376f4d5a03a3dfc9d4ca30074b3df3e424bd7e4bDonghyun Cho } 1478005482649154d0970693b3967241eb4d2cb22003Jaewan Kim } 14796051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo} 1480