180f4e792d835145cebaab8a4abed16284624188eJae Seo/*
2816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * Copyright (C) 2015 The Android Open Source Project
380f4e792d835145cebaab8a4abed16284624188eJae Seo *
480f4e792d835145cebaab8a4abed16284624188eJae Seo * Licensed under the Apache License, Version 2.0 (the "License");
580f4e792d835145cebaab8a4abed16284624188eJae Seo * you may not use this file except in compliance with the License.
680f4e792d835145cebaab8a4abed16284624188eJae Seo * You may obtain a copy of the License at
780f4e792d835145cebaab8a4abed16284624188eJae Seo *
880f4e792d835145cebaab8a4abed16284624188eJae Seo *      http://www.apache.org/licenses/LICENSE-2.0
980f4e792d835145cebaab8a4abed16284624188eJae Seo *
1080f4e792d835145cebaab8a4abed16284624188eJae Seo * Unless required by applicable law or agreed to in writing, software
1180f4e792d835145cebaab8a4abed16284624188eJae Seo * distributed under the License is distributed on an "AS IS" BASIS,
1280f4e792d835145cebaab8a4abed16284624188eJae Seo * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1380f4e792d835145cebaab8a4abed16284624188eJae Seo * See the License for the specific language governing permissions and
1480f4e792d835145cebaab8a4abed16284624188eJae Seo * limitations under the License.
1580f4e792d835145cebaab8a4abed16284624188eJae Seo */
162ea620f3fa5af5bf4ca1a881fd480f0bad34fc1dJaekyun Seok
172ea620f3fa5af5bf4ca1a881fd480f0bad34fc1dJaekyun Seokpackage com.android.tv.ui;
182ea620f3fa5af5bf4ca1a881fd480f0bad34fc1dJaekyun Seok
19816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport android.animation.Animator;
20816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport android.animation.AnimatorInflater;
21816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport android.animation.AnimatorListenerAdapter;
22816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport android.animation.AnimatorSet;
23816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport android.animation.ValueAnimator;
242ea620f3fa5af5bf4ca1a881fd480f0bad34fc1dJaekyun Seokimport android.content.Context;
25816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport android.content.res.Resources;
262ea620f3fa5af5bf4ca1a881fd480f0bad34fc1dJaekyun Seokimport android.database.ContentObserver;
277e81e7a0ac50567219dc098c59f5c04e02a4f591Ji-Hwan Leeimport android.graphics.Bitmap;
284e5a6a47adb40039a27536236656204f9ad12df3Jaewan Kimimport android.media.tv.TvContract;
2987c1cbb508c96538d1e69ba1fdf3d9f4d52710d6Jaewan Kimimport android.media.tv.TvInputInfo;
302ea620f3fa5af5bf4ca1a881fd480f0bad34fc1dJaekyun Seokimport android.net.Uri;
312ea620f3fa5af5bf4ca1a881fd480f0bad34fc1dJaekyun Seokimport android.os.Handler;
32ba5845f23b8fbc985890f892961abc8b39886611Nick Chalkoimport android.support.annotation.Nullable;
33816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport android.text.Spannable;
34816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport android.text.SpannableString;
352ea620f3fa5af5bf4ca1a881fd480f0bad34fc1dJaekyun Seokimport android.text.TextUtils;
3648dadb49248271b01997862e1335912a4f2e189fYoungsang Choimport android.text.format.DateUtils;
37816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport android.text.style.TextAppearanceSpan;
382ea620f3fa5af5bf4ca1a881fd480f0bad34fc1dJaekyun Seokimport android.util.AttributeSet;
3948dadb49248271b01997862e1335912a4f2e189fYoungsang Choimport android.util.Log;
4074c3e85f22082f34c1a822d268ff2da48ebefdbdJaewan Kimimport android.util.TypedValue;
41f533911c31daa05e2ad955434c55b4d412673656Jaekyun Seokimport android.view.View;
42816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport android.view.ViewGroup;
43816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport android.view.animation.AnimationUtils;
44816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport android.view.animation.Interpolator;
45816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport android.widget.FrameLayout;
4674c3e85f22082f34c1a822d268ff2da48ebefdbdJaewan Kimimport android.widget.ImageView;
47f533911c31daa05e2ad955434c55b4d412673656Jaekyun Seokimport android.widget.ProgressBar;
4874c3e85f22082f34c1a822d268ff2da48ebefdbdJaewan Kimimport android.widget.RelativeLayout;
492ea620f3fa5af5bf4ca1a881fd480f0bad34fc1dJaekyun Seokimport android.widget.TextView;
502ea620f3fa5af5bf4ca1a881fd480f0bad34fc1dJaekyun Seok
51816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport com.android.tv.MainActivity;
5280f4e792d835145cebaab8a4abed16284624188eJae Seoimport com.android.tv.R;
5348dadb49248271b01997862e1335912a4f2e189fYoungsang Choimport com.android.tv.common.recording.RecordedProgram;
547e81e7a0ac50567219dc098c59f5c04e02a4f591Ji-Hwan Leeimport com.android.tv.data.Channel;
55d422754c0cc8475d6e2c8c079ed2ee2e96213edbChulwoo Leeimport com.android.tv.data.Program;
5621abb13274f379e69c3c86d51e493122cccca345Dongwon Kangimport com.android.tv.data.StreamInfo;
57816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport com.android.tv.util.ImageCache;
58816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport com.android.tv.util.ImageLoader;
5948dadb49248271b01997862e1335912a4f2e189fYoungsang Choimport com.android.tv.util.ImageLoader.ImageLoaderCallback;
60816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport com.android.tv.util.ImageLoader.LoadTvInputLogoTask;
61d422754c0cc8475d6e2c8c079ed2ee2e96213edbChulwoo Leeimport com.android.tv.util.Utils;
6280f4e792d835145cebaab8a4abed16284624188eJae Seo
63816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport junit.framework.Assert;
64816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
65816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport java.util.Objects;
66816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
672ea620f3fa5af5bf4ca1a881fd480f0bad34fc1dJaekyun Seok/**
682ea620f3fa5af5bf4ca1a881fd480f0bad34fc1dJaekyun Seok * A view to render channel banner.
692ea620f3fa5af5bf4ca1a881fd480f0bad34fc1dJaekyun Seok */
70ba5845f23b8fbc985890f892961abc8b39886611Nick Chalkopublic class ChannelBannerView extends FrameLayout implements TvTransitionManager.TransitionLayout {
7148dadb49248271b01997862e1335912a4f2e189fYoungsang Cho    private static final String TAG = "ChannelBannerView";
7248dadb49248271b01997862e1335912a4f2e189fYoungsang Cho    private static final boolean DEBUG = false;
73816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
74816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    /**
75816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko     * Show all information at the channel banner.
76816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko     */
77816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    public static final int LOCK_NONE = 0;
78816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
79816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    /**
80816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko     * Lock program details at the channel banner.
81816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko     * This is used when a content is locked so we don't want to show program details
82816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko     * including program description text and poster art.
83816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko     */
84816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    public static final int LOCK_PROGRAM_DETAIL = 1;
85816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
86816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    /**
87816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko     * Lock channel information at the channel banner.
88816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko     * This is used when a channel is locked so we only want to show input information.
89816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko     */
90816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    public static final int LOCK_CHANNEL_INFO = 2;
91816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
92816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    private static final String EMPTY_STRING = "";
93816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
94816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    private static Program sNoProgram;
95816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    private static Program sLockedChannelProgram;
96816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    private static String sClosedCaptionMark;
97816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
98816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    private final MainActivity mMainActivity;
99816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    private final Resources mResources;
100816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    private View mChannelView;
101816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
102816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    private TextView mChannelNumberTextView;
1034e5a6a47adb40039a27536236656204f9ad12df3Jaewan Kim    private ImageView mChannelLogoImageView;
1044e5a6a47adb40039a27536236656204f9ad12df3Jaewan Kim    private TextView mProgramTextView;
1054e5a6a47adb40039a27536236656204f9ad12df3Jaewan Kim    private ImageView mTvInputLogoImageView;
1064e5a6a47adb40039a27536236656204f9ad12df3Jaewan Kim    private TextView mChannelNameTextView;
1074e5a6a47adb40039a27536236656204f9ad12df3Jaewan Kim    private TextView mProgramTimeTextView;
1084e5a6a47adb40039a27536236656204f9ad12df3Jaewan Kim    private ProgressBar mRemainingTimeView;
109e51a084c2518f17cee43c86e2f9df907d1f2cafbDongwon Kang    private TextView mClosedCaptionTextView;
110f533911c31daa05e2ad955434c55b4d412673656Jaekyun Seok    private TextView mAspectRatioTextView;
1114e5a6a47adb40039a27536236656204f9ad12df3Jaewan Kim    private TextView mResolutionTextView;
112e51a084c2518f17cee43c86e2f9df907d1f2cafbDongwon Kang    private TextView mAudioChannelTextView;
113816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    private TextView mProgramDescriptionTextView;
114816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    private String mProgramDescriptionText;
1157759a43e3ef38a66aba4b8f7b266a94dc7b491e1Ji-Hwan Lee    private View mAnchorView;
116816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    private Channel mCurrentChannel;
117816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    private Program mLastUpdatedProgram;
11848dadb49248271b01997862e1335912a4f2e189fYoungsang Cho    private RecordedProgram mLastUpdatedRecordedProgram;
119816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    private final Handler mHandler = new Handler();
120816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
121816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    private int mLockType;
122816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
123816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    private Animator mResizeAnimator;
124816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    private int mCurrentHeight;
125816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    private boolean mProgramInfoUpdatePendingByResizing;
126816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
127816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    private final Animator mProgramDescriptionFadeInAnimator;
128816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    private final Animator mProgramDescriptionFadeOutAnimator;
129816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
130816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    private final Runnable mHideRunnable = new Runnable() {
131816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        @Override
132816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        public void run() {
133816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            mCurrentHeight = 0;
13407b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko            mMainActivity.getOverlayManager().hideOverlays(
13507b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko                    TvOverlayManager.FLAG_HIDE_OVERLAYS_KEEP_DIALOG
13607b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko                    | TvOverlayManager.FLAG_HIDE_OVERLAYS_KEEP_SIDE_PANELS
13707b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko                    | TvOverlayManager.FLAG_HIDE_OVERLAYS_KEEP_PROGRAM_GUIDE
138ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko                    | TvOverlayManager.FLAG_HIDE_OVERLAYS_KEEP_MENU
139ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko                    | TvOverlayManager.FLAG_HIDE_OVERLAYS_KEEP_FRAGMENT);
140816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        }
141816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    };
142816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    private final long mShowDurationMillis;
143816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    private final int mChannelLogoImageViewWidth;
144816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    private final int mChannelLogoImageViewHeight;
145816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    private final int mChannelLogoImageViewMarginStart;
146816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    private final int mProgramDescriptionTextViewWidth;
147816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    private final int mChannelBannerTextColor;
148816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    private final int mChannelBannerDimTextColor;
149816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    private final int mResizeAnimDuration;
150816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    private final Interpolator mResizeInterpolator;
151816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
152816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    private final AnimatorListenerAdapter mResizeAnimatorListener = new AnimatorListenerAdapter() {
153816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        @Override
154816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        public void onAnimationStart(Animator animator) {
155816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            mProgramInfoUpdatePendingByResizing = false;
156816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        }
1572ea620f3fa5af5bf4ca1a881fd480f0bad34fc1dJaekyun Seok
158816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        @Override
159816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        public void onAnimationEnd(Animator animator) {
160816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            mProgramDescriptionTextView.setAlpha(1f);
161816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            mResizeAnimator = null;
162816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            if (mProgramInfoUpdatePendingByResizing) {
163816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                mProgramInfoUpdatePendingByResizing = false;
164816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                updateProgramInfo(mLastUpdatedProgram);
165816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            }
166816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        }
167816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    };
168816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
169816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    private final ContentObserver mProgramUpdateObserver = new ContentObserver(mHandler) {
1702ea620f3fa5af5bf4ca1a881fd480f0bad34fc1dJaekyun Seok        @Override
1712ea620f3fa5af5bf4ca1a881fd480f0bad34fc1dJaekyun Seok        public void onChange(boolean selfChange, Uri uri) {
172aa92e04c7c38bba1456b4f02dc3a764233dff24aDongwon Kang            // TODO: This {@code uri} argument may be a program which is not related to this
173aa92e04c7c38bba1456b4f02dc3a764233dff24aDongwon Kang            // channel. Consider adding channel id as a parameter of program URI to avoid
174aa92e04c7c38bba1456b4f02dc3a764233dff24aDongwon Kang            // unnecessary update.
175816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            mHandler.post(mProgramUpdateRunnable);
176aa92e04c7c38bba1456b4f02dc3a764233dff24aDongwon Kang        }
177aa92e04c7c38bba1456b4f02dc3a764233dff24aDongwon Kang    };
178aa92e04c7c38bba1456b4f02dc3a764233dff24aDongwon Kang
179aa92e04c7c38bba1456b4f02dc3a764233dff24aDongwon Kang    private final Runnable mProgramUpdateRunnable = new Runnable() {
180aa92e04c7c38bba1456b4f02dc3a764233dff24aDongwon Kang        @Override
181aa92e04c7c38bba1456b4f02dc3a764233dff24aDongwon Kang        public void run() {
182aa92e04c7c38bba1456b4f02dc3a764233dff24aDongwon Kang            removeCallbacks(this);
183816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            updateViews(null);
1842ea620f3fa5af5bf4ca1a881fd480f0bad34fc1dJaekyun Seok        }
1852ea620f3fa5af5bf4ca1a881fd480f0bad34fc1dJaekyun Seok    };
1862ea620f3fa5af5bf4ca1a881fd480f0bad34fc1dJaekyun Seok
1872ea620f3fa5af5bf4ca1a881fd480f0bad34fc1dJaekyun Seok    public ChannelBannerView(Context context) {
18807097678613a4ebd094fd8a7ccae5d2aa3fa642aJi-Hwan Lee        this(context, null);
1892ea620f3fa5af5bf4ca1a881fd480f0bad34fc1dJaekyun Seok    }
1902ea620f3fa5af5bf4ca1a881fd480f0bad34fc1dJaekyun Seok
1912ea620f3fa5af5bf4ca1a881fd480f0bad34fc1dJaekyun Seok    public ChannelBannerView(Context context, AttributeSet attrs) {
192816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        this(context, attrs, 0);
1932ea620f3fa5af5bf4ca1a881fd480f0bad34fc1dJaekyun Seok    }
1942ea620f3fa5af5bf4ca1a881fd480f0bad34fc1dJaekyun Seok
1952ea620f3fa5af5bf4ca1a881fd480f0bad34fc1dJaekyun Seok    public ChannelBannerView(Context context, AttributeSet attrs, int defStyle) {
1962ea620f3fa5af5bf4ca1a881fd480f0bad34fc1dJaekyun Seok        super(context, attrs, defStyle);
197816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        mResources = getResources();
198816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
199816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        mMainActivity = (MainActivity) context;
200816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
201816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        mShowDurationMillis = mResources.getInteger(
202816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                R.integer.channel_banner_show_duration);
203816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        mChannelLogoImageViewWidth = mResources.getDimensionPixelSize(
204816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                R.dimen.channel_banner_channel_logo_width);
205816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        mChannelLogoImageViewHeight = mResources.getDimensionPixelSize(
206816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                R.dimen.channel_banner_channel_logo_height);
207816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        mChannelLogoImageViewMarginStart = mResources.getDimensionPixelSize(
208816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                R.dimen.channel_banner_channel_logo_margin_start);
209816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        mProgramDescriptionTextViewWidth = mResources.getDimensionPixelSize(
210816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                R.dimen.channel_banner_program_description_width);
2117d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko        mChannelBannerTextColor = Utils.getColor(mResources, R.color.channel_banner_text_color);
2127d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko        mChannelBannerDimTextColor = Utils.getColor(mResources,
2137d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko                R.color.channel_banner_dim_text_color);
214816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        mResizeAnimDuration = mResources.getInteger(R.integer.channel_banner_fast_anim_duration);
215816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
216816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        mResizeInterpolator = AnimationUtils.loadInterpolator(context,
217816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                android.R.interpolator.linear_out_slow_in);
218816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
219816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        mProgramDescriptionFadeInAnimator = AnimatorInflater.loadAnimator(mMainActivity,
220816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                R.animator.channel_banner_program_description_fade_in);
221816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        mProgramDescriptionFadeOutAnimator = AnimatorInflater.loadAnimator(mMainActivity,
222816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                R.animator.channel_banner_program_description_fade_out);
223816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
224816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        if (sNoProgram == null) {
225816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            sNoProgram = new Program.Builder()
226816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                    .setTitle(context.getString(R.string.channel_banner_no_title))
227816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                    .setDescription(EMPTY_STRING)
228816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                    .build();
229816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        }
230816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        if (sLockedChannelProgram == null){
231816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            sLockedChannelProgram = new Program.Builder()
232816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                    .setTitle(context.getString(R.string.channel_banner_locked_channel_title))
233816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                    .setDescription(EMPTY_STRING)
234816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                    .build();
235816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        }
236816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        if (sClosedCaptionMark == null) {
237816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            sClosedCaptionMark = context.getString(R.string.closed_caption);
238816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        }
2392ea620f3fa5af5bf4ca1a881fd480f0bad34fc1dJaekyun Seok    }
2402ea620f3fa5af5bf4ca1a881fd480f0bad34fc1dJaekyun Seok
2412ea620f3fa5af5bf4ca1a881fd480f0bad34fc1dJaekyun Seok    @Override
2422ea620f3fa5af5bf4ca1a881fd480f0bad34fc1dJaekyun Seok    protected void onAttachedToWindow() {
24348dadb49248271b01997862e1335912a4f2e189fYoungsang Cho        if (DEBUG) Log.d(TAG, "onAttachedToWindow");
2442ea620f3fa5af5bf4ca1a881fd480f0bad34fc1dJaekyun Seok        super.onAttachedToWindow();
2452ea620f3fa5af5bf4ca1a881fd480f0bad34fc1dJaekyun Seok        getContext().getContentResolver().registerContentObserver(TvContract.Programs.CONTENT_URI,
2462ea620f3fa5af5bf4ca1a881fd480f0bad34fc1dJaekyun Seok                true, mProgramUpdateObserver);
2472ea620f3fa5af5bf4ca1a881fd480f0bad34fc1dJaekyun Seok    }
2482ea620f3fa5af5bf4ca1a881fd480f0bad34fc1dJaekyun Seok
2492ea620f3fa5af5bf4ca1a881fd480f0bad34fc1dJaekyun Seok    @Override
2502ea620f3fa5af5bf4ca1a881fd480f0bad34fc1dJaekyun Seok    protected void onDetachedFromWindow() {
25148dadb49248271b01997862e1335912a4f2e189fYoungsang Cho        if (DEBUG) Log.d(TAG, "onDetachedToWindow");
2522ea620f3fa5af5bf4ca1a881fd480f0bad34fc1dJaekyun Seok        getContext().getContentResolver().unregisterContentObserver(mProgramUpdateObserver);
2532ea620f3fa5af5bf4ca1a881fd480f0bad34fc1dJaekyun Seok        super.onDetachedFromWindow();
2542ea620f3fa5af5bf4ca1a881fd480f0bad34fc1dJaekyun Seok    }
2552ea620f3fa5af5bf4ca1a881fd480f0bad34fc1dJaekyun Seok
2562ea620f3fa5af5bf4ca1a881fd480f0bad34fc1dJaekyun Seok    @Override
2572ea620f3fa5af5bf4ca1a881fd480f0bad34fc1dJaekyun Seok    protected void onFinishInflate() {
2582ea620f3fa5af5bf4ca1a881fd480f0bad34fc1dJaekyun Seok        super.onFinishInflate();
2592ea620f3fa5af5bf4ca1a881fd480f0bad34fc1dJaekyun Seok
260816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        mChannelView = findViewById(R.id.channel_banner_view);
261816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
262816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        mChannelNumberTextView = (TextView) findViewById(R.id.channel_number);
2634e5a6a47adb40039a27536236656204f9ad12df3Jaewan Kim        mChannelLogoImageView = (ImageView) findViewById(R.id.channel_logo);
2644e5a6a47adb40039a27536236656204f9ad12df3Jaewan Kim        mProgramTextView = (TextView) findViewById(R.id.program_text);
2654e5a6a47adb40039a27536236656204f9ad12df3Jaewan Kim        mTvInputLogoImageView = (ImageView) findViewById(R.id.tvinput_logo);
2664e5a6a47adb40039a27536236656204f9ad12df3Jaewan Kim        mChannelNameTextView = (TextView) findViewById(R.id.channel_name);
2674e5a6a47adb40039a27536236656204f9ad12df3Jaewan Kim        mProgramTimeTextView = (TextView) findViewById(R.id.program_time_text);
2684e5a6a47adb40039a27536236656204f9ad12df3Jaewan Kim        mRemainingTimeView = (ProgressBar) findViewById(R.id.remaining_time);
269e51a084c2518f17cee43c86e2f9df907d1f2cafbDongwon Kang        mClosedCaptionTextView = (TextView) findViewById(R.id.closed_caption);
270f533911c31daa05e2ad955434c55b4d412673656Jaekyun Seok        mAspectRatioTextView = (TextView) findViewById(R.id.aspect_ratio);
2714e5a6a47adb40039a27536236656204f9ad12df3Jaewan Kim        mResolutionTextView = (TextView) findViewById(R.id.resolution);
272e51a084c2518f17cee43c86e2f9df907d1f2cafbDongwon Kang        mAudioChannelTextView = (TextView) findViewById(R.id.audio_channel);
273816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        mProgramDescriptionTextView = (TextView) findViewById(R.id.program_description);
2747759a43e3ef38a66aba4b8f7b266a94dc7b491e1Ji-Hwan Lee        mAnchorView = findViewById(R.id.anchor);
275816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
276816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        mProgramDescriptionFadeInAnimator.setTarget(mProgramDescriptionTextView);
277816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        mProgramDescriptionFadeOutAnimator.setTarget(mProgramDescriptionTextView);
278816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        mProgramDescriptionFadeOutAnimator.addListener(new AnimatorListenerAdapter() {
279816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            @Override
280816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            public void onAnimationEnd(Animator animator) {
281816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                mProgramDescriptionTextView.setText(mProgramDescriptionText);
282816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            }
283816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        });
2842ea620f3fa5af5bf4ca1a881fd480f0bad34fc1dJaekyun Seok    }
2852ea620f3fa5af5bf4ca1a881fd480f0bad34fc1dJaekyun Seok
286816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    @Override
287816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    public void onEnterAction(boolean fromEmptyScene) {
288816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        resetAnimationEffects();
289816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        if (fromEmptyScene) {
290816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            ViewUtils.setTransitionAlpha(mChannelView, 1f);
291816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        }
292816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        scheduleHide();
293816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    }
294816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
295816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    @Override
296816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    public void onExitAction() {
297816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        mCurrentHeight = 0;
298816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        cancelHide();
299816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    }
300816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
301816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    private void scheduleHide() {
302816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        cancelHide();
303816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        mHandler.postDelayed(mHideRunnable, mShowDurationMillis);
304816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    }
305816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
306816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    private void cancelHide() {
307816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        mHandler.removeCallbacks(mHideRunnable);
308816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    }
309816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
310816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    private void resetAnimationEffects() {
311816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        setAlpha(1f);
312816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        setScaleX(1f);
313816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        setScaleY(1f);
314816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        setTranslationX(0);
315816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        setTranslationY(0);
316816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    }
317816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
318816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    /**
319816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko     * Set new lock type.
320816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko     *
321816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko     * @param lockType Any of LOCK_NONE, LOCK_PROGRAM_DETAIL, or LOCK_CHANNEL_INFO.
322816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko     * @return {@code true} only if lock type is changed
323816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko     * @throws IllegalArgumentException if lockType is invalid.
324816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko     */
325816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    public boolean setLockType(int lockType) {
326816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        if (lockType != LOCK_NONE && lockType != LOCK_CHANNEL_INFO
327816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                && lockType != LOCK_PROGRAM_DETAIL) {
328816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            throw new IllegalArgumentException("No such lock type " + lockType);
329816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        }
330816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        if (mLockType != lockType) {
331816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            mLockType = lockType;
332816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            return true;
333816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        }
334816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        return false;
335816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    }
336816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
337816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    /**
338816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko     * Update channel banner view.
339816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko     *
340816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko     * @param info A StreamInfo that includes stream information.
341816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko     * If it's {@code null}, only program information will be updated.
342816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko     */
343816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    public void updateViews(StreamInfo info) {
344816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        resetAnimationEffects();
345816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        Channel channel = mMainActivity.getCurrentChannel();
346816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        if (!Objects.equals(mCurrentChannel, channel) && isShown()) {
347816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            scheduleHide();
348816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        }
349816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        mCurrentChannel = channel;
350816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        mChannelView.setVisibility(VISIBLE);
351816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        if (info != null) {
352816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            // If the current channels between ChannelTuner and TvView are different,
353816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            // the stream information should not be seen.
35448dadb49248271b01997862e1335912a4f2e189fYoungsang Cho            updateStreamInfo(channel != null && channel.equals(info.getCurrentChannel()) ? info
35548dadb49248271b01997862e1335912a4f2e189fYoungsang Cho                    : null);
356816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            updateChannelInfo();
357816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        }
35848dadb49248271b01997862e1335912a4f2e189fYoungsang Cho        if (mMainActivity.isRecordingPlayback()) {
35948dadb49248271b01997862e1335912a4f2e189fYoungsang Cho            updateProgramInfo(mMainActivity.getPlayingRecordedProgram());
36048dadb49248271b01997862e1335912a4f2e189fYoungsang Cho        } else {
36148dadb49248271b01997862e1335912a4f2e189fYoungsang Cho            updateProgramInfo(mMainActivity.getCurrentProgram());
36248dadb49248271b01997862e1335912a4f2e189fYoungsang Cho        }
363816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    }
364816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
365816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    private void updateStreamInfo(StreamInfo info) {
366816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        // Update stream information in a channel.
367816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        if (mLockType != LOCK_CHANNEL_INFO && info != null) {
368816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            updateText(mClosedCaptionTextView, info.hasClosedCaption() ? sClosedCaptionMark
369816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                    : EMPTY_STRING);
370816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            updateText(mAspectRatioTextView,
37148dadb49248271b01997862e1335912a4f2e189fYoungsang Cho                    Utils.getAspectRatioString(info.getVideoDisplayAspectRatio()));
372816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            updateText(mResolutionTextView,
373816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                    Utils.getVideoDefinitionLevelString(
374816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                            mMainActivity, info.getVideoDefinitionLevel()));
375816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            updateText(mAudioChannelTextView,
376816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                    Utils.getAudioChannelString(mMainActivity, info.getAudioChannelCount()));
377816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        } else {
378816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            // Channel change has been requested. But, StreamInfo hasn't been updated yet.
379816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            mClosedCaptionTextView.setVisibility(View.GONE);
380816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            mAspectRatioTextView.setVisibility(View.GONE);
381816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            mResolutionTextView.setVisibility(View.GONE);
382816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            mAudioChannelTextView.setVisibility(View.GONE);
383816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        }
384816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    }
38587c1cbb508c96538d1e69ba1fdf3d9f4d52710d6Jaewan Kim
386816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    private void updateChannelInfo() {
387816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        // Update static information for a channel.
38848dadb49248271b01997862e1335912a4f2e189fYoungsang Cho        String displayNumber = EMPTY_STRING;
38948dadb49248271b01997862e1335912a4f2e189fYoungsang Cho        String displayName = EMPTY_STRING;
39048dadb49248271b01997862e1335912a4f2e189fYoungsang Cho        if (mCurrentChannel != null) {
39148dadb49248271b01997862e1335912a4f2e189fYoungsang Cho            displayNumber = mCurrentChannel.getDisplayNumber();
39248dadb49248271b01997862e1335912a4f2e189fYoungsang Cho            if (displayNumber == null) {
39348dadb49248271b01997862e1335912a4f2e189fYoungsang Cho                displayNumber = EMPTY_STRING;
39448dadb49248271b01997862e1335912a4f2e189fYoungsang Cho            }
39548dadb49248271b01997862e1335912a4f2e189fYoungsang Cho            displayName = mCurrentChannel.getDisplayName();
39648dadb49248271b01997862e1335912a4f2e189fYoungsang Cho            if (displayName == null) {
39748dadb49248271b01997862e1335912a4f2e189fYoungsang Cho                displayName = EMPTY_STRING;
39848dadb49248271b01997862e1335912a4f2e189fYoungsang Cho            }
399f533911c31daa05e2ad955434c55b4d412673656Jaekyun Seok        }
40007097678613a4ebd094fd8a7ccae5d2aa3fa642aJi-Hwan Lee
40148dadb49248271b01997862e1335912a4f2e189fYoungsang Cho        if (displayNumber.isEmpty()) {
40248dadb49248271b01997862e1335912a4f2e189fYoungsang Cho            mChannelNumberTextView.setVisibility(GONE);
40348dadb49248271b01997862e1335912a4f2e189fYoungsang Cho        } else {
40448dadb49248271b01997862e1335912a4f2e189fYoungsang Cho            mChannelNumberTextView.setVisibility(VISIBLE);
40548dadb49248271b01997862e1335912a4f2e189fYoungsang Cho        }
40674c3e85f22082f34c1a822d268ff2da48ebefdbdJaewan Kim        if (displayNumber.length() <= 3) {
40707097678613a4ebd094fd8a7ccae5d2aa3fa642aJi-Hwan Lee            updateTextView(
408816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                    mChannelNumberTextView,
409816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                    R.dimen.channel_banner_channel_number_large_text_size,
410816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                    R.dimen.channel_banner_channel_number_large_margin_top);
41174c3e85f22082f34c1a822d268ff2da48ebefdbdJaewan Kim        } else if (displayNumber.length() <= 4) {
41207097678613a4ebd094fd8a7ccae5d2aa3fa642aJi-Hwan Lee            updateTextView(
413816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                    mChannelNumberTextView,
414816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                    R.dimen.channel_banner_channel_number_medium_text_size,
415816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                    R.dimen.channel_banner_channel_number_medium_margin_top);
41674c3e85f22082f34c1a822d268ff2da48ebefdbdJaewan Kim        } else {
41707097678613a4ebd094fd8a7ccae5d2aa3fa642aJi-Hwan Lee            updateTextView(
418816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                    mChannelNumberTextView,
419816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                    R.dimen.channel_banner_channel_number_small_text_size,
420816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                    R.dimen.channel_banner_channel_number_small_margin_top);
42174c3e85f22082f34c1a822d268ff2da48ebefdbdJaewan Kim        }
422816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        mChannelNumberTextView.setText(displayNumber);
423e51a084c2518f17cee43c86e2f9df907d1f2cafbDongwon Kang        mChannelNameTextView.setText(displayName);
424816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        TvInputInfo info = mMainActivity.getTvInputManagerHelper().getTvInputInfo(
42548dadb49248271b01997862e1335912a4f2e189fYoungsang Cho                getCurrentInputId());
426ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko        if (info == null || !ImageLoader.loadBitmap(createTvInputLogoLoaderCallback(info, this),
427816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                        new LoadTvInputLogoTask(getContext(), ImageCache.getInstance(), info))) {
428816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            mTvInputLogoImageView.setVisibility(View.GONE);
429816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            mTvInputLogoImageView.setImageDrawable(null);
430e08dee8c8613aa52183d710dbcda28acd3dfa5c8Chulwoo Lee        }
431816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        mChannelLogoImageView.setImageBitmap(null);
432816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        mChannelLogoImageView.setVisibility(View.GONE);
43348dadb49248271b01997862e1335912a4f2e189fYoungsang Cho        if (mCurrentChannel != null) {
43448dadb49248271b01997862e1335912a4f2e189fYoungsang Cho            mCurrentChannel.loadBitmap(getContext(), Channel.LOAD_IMAGE_TYPE_CHANNEL_LOGO,
43548dadb49248271b01997862e1335912a4f2e189fYoungsang Cho                    mChannelLogoImageViewWidth, mChannelLogoImageViewHeight,
43648dadb49248271b01997862e1335912a4f2e189fYoungsang Cho                    createChannelLogoCallback(this, mCurrentChannel));
43748dadb49248271b01997862e1335912a4f2e189fYoungsang Cho        }
43848dadb49248271b01997862e1335912a4f2e189fYoungsang Cho    }
43948dadb49248271b01997862e1335912a4f2e189fYoungsang Cho
44048dadb49248271b01997862e1335912a4f2e189fYoungsang Cho    private String getCurrentInputId() {
44148dadb49248271b01997862e1335912a4f2e189fYoungsang Cho        Channel channel = mMainActivity.getCurrentChannel();
44248dadb49248271b01997862e1335912a4f2e189fYoungsang Cho        if (channel != null) {
44348dadb49248271b01997862e1335912a4f2e189fYoungsang Cho            return channel.getInputId();
44448dadb49248271b01997862e1335912a4f2e189fYoungsang Cho        } else if (mMainActivity.isRecordingPlayback()) {
44548dadb49248271b01997862e1335912a4f2e189fYoungsang Cho            RecordedProgram recordedProgram = mMainActivity.getPlayingRecordedProgram();
44648dadb49248271b01997862e1335912a4f2e189fYoungsang Cho            if (recordedProgram != null) {
44748dadb49248271b01997862e1335912a4f2e189fYoungsang Cho                return recordedProgram.getInputId();
44848dadb49248271b01997862e1335912a4f2e189fYoungsang Cho            }
44948dadb49248271b01997862e1335912a4f2e189fYoungsang Cho        }
45048dadb49248271b01997862e1335912a4f2e189fYoungsang Cho        return null;
451ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko    }
452ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko
453ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko    private void updateTvInputLogo(Bitmap bitmap) {
454ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko        mTvInputLogoImageView.setVisibility(View.VISIBLE);
455ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko        mTvInputLogoImageView.setImageBitmap(bitmap);
456816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    }
45707097678613a4ebd094fd8a7ccae5d2aa3fa642aJi-Hwan Lee
458ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko    private static ImageLoaderCallback<ChannelBannerView> createTvInputLogoLoaderCallback(
459ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko            final TvInputInfo info, ChannelBannerView channelBannerView) {
460ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko        return new ImageLoaderCallback<ChannelBannerView>(channelBannerView) {
461816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            @Override
462ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko            public void onBitmapLoaded(ChannelBannerView channelBannerView, Bitmap bitmap) {
46348dadb49248271b01997862e1335912a4f2e189fYoungsang Cho                if (bitmap != null && channelBannerView.mCurrentChannel != null
46448dadb49248271b01997862e1335912a4f2e189fYoungsang Cho                        && info.getId().equals(channelBannerView.mCurrentChannel.getInputId())) {
465ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko                    channelBannerView.updateTvInputLogo(bitmap);
466816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                }
467816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            }
468816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        };
4692ea620f3fa5af5bf4ca1a881fd480f0bad34fc1dJaekyun Seok    }
4702ea620f3fa5af5bf4ca1a881fd480f0bad34fc1dJaekyun Seok
4714e5a6a47adb40039a27536236656204f9ad12df3Jaewan Kim    private void updateText(TextView view, String text) {
4724e5a6a47adb40039a27536236656204f9ad12df3Jaewan Kim        if (TextUtils.isEmpty(text)) {
4734e5a6a47adb40039a27536236656204f9ad12df3Jaewan Kim            view.setVisibility(View.GONE);
4744e5a6a47adb40039a27536236656204f9ad12df3Jaewan Kim        } else {
4754e5a6a47adb40039a27536236656204f9ad12df3Jaewan Kim            view.setVisibility(View.VISIBLE);
4764e5a6a47adb40039a27536236656204f9ad12df3Jaewan Kim            view.setText(text);
4774e5a6a47adb40039a27536236656204f9ad12df3Jaewan Kim        }
4784e5a6a47adb40039a27536236656204f9ad12df3Jaewan Kim    }
4794e5a6a47adb40039a27536236656204f9ad12df3Jaewan Kim
48007097678613a4ebd094fd8a7ccae5d2aa3fa642aJi-Hwan Lee    private void updateTextView(TextView textView, int sizeRes, int marginTopRes) {
481816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        float textSize = mResources.getDimension(sizeRes);
4827759a43e3ef38a66aba4b8f7b266a94dc7b491e1Ji-Hwan Lee        if (textView.getTextSize() != textSize) {
4837759a43e3ef38a66aba4b8f7b266a94dc7b491e1Ji-Hwan Lee            textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize);
4847759a43e3ef38a66aba4b8f7b266a94dc7b491e1Ji-Hwan Lee        }
4857759a43e3ef38a66aba4b8f7b266a94dc7b491e1Ji-Hwan Lee        updateTopMargin(textView, marginTopRes);
4867759a43e3ef38a66aba4b8f7b266a94dc7b491e1Ji-Hwan Lee    }
4877759a43e3ef38a66aba4b8f7b266a94dc7b491e1Ji-Hwan Lee
4887759a43e3ef38a66aba4b8f7b266a94dc7b491e1Ji-Hwan Lee    private void updateTopMargin(View view, int marginTopRes) {
489816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) view.getLayoutParams();
490816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        int topMargin = (int) mResources.getDimension(marginTopRes);
4917759a43e3ef38a66aba4b8f7b266a94dc7b491e1Ji-Hwan Lee        if (lp.topMargin != topMargin) {
4927759a43e3ef38a66aba4b8f7b266a94dc7b491e1Ji-Hwan Lee            lp.topMargin = topMargin;
4937759a43e3ef38a66aba4b8f7b266a94dc7b491e1Ji-Hwan Lee            view.setLayoutParams(lp);
4947759a43e3ef38a66aba4b8f7b266a94dc7b491e1Ji-Hwan Lee        }
49507097678613a4ebd094fd8a7ccae5d2aa3fa642aJi-Hwan Lee    }
49607097678613a4ebd094fd8a7ccae5d2aa3fa642aJi-Hwan Lee
497ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko    private static ImageLoaderCallback<ChannelBannerView> createChannelLogoCallback(
498ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko            ChannelBannerView channelBannerView, final Channel channel) {
499ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko        return new ImageLoaderCallback<ChannelBannerView>(channelBannerView) {
500ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko            @Override
501ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko            public void onBitmapLoaded(ChannelBannerView view, @Nullable Bitmap logo) {
502ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko                if (channel != view.mCurrentChannel) {
503ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko                    // The logo is obsolete.
504ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko                    return;
505ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko                }
506ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko                view.updateLogo(logo);
507ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko            }
508ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko        };
509ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko    }
510ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko
511ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko    private void updateLogo(@Nullable Bitmap logo) {
5127e81e7a0ac50567219dc098c59f5c04e02a4f591Ji-Hwan Lee        if (logo == null) {
513816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            // Need to update the text size of the program text view depending on the channel logo.
514816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            updateProgramTextView(mLastUpdatedProgram);
515816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            return;
516816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        }
517816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
518816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        mChannelLogoImageView.setImageBitmap(logo);
519816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        mChannelLogoImageView.setVisibility(View.VISIBLE);
520816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        updateProgramTextView(mLastUpdatedProgram);
521816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
522816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        if (mResizeAnimator == null) {
523816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            String description = mProgramDescriptionTextView.getText().toString();
524816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            boolean needFadeAnimation = !description.equals(mProgramDescriptionText);
525816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            updateBannerHeight(needFadeAnimation);
5267e81e7a0ac50567219dc098c59f5c04e02a4f591Ji-Hwan Lee        } else {
527816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            mProgramInfoUpdatePendingByResizing = true;
5287e81e7a0ac50567219dc098c59f5c04e02a4f591Ji-Hwan Lee        }
5297e81e7a0ac50567219dc098c59f5c04e02a4f591Ji-Hwan Lee    }
5307e81e7a0ac50567219dc098c59f5c04e02a4f591Ji-Hwan Lee
531816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    private void updateProgramInfo(Program program) {
532816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        if (mLockType == LOCK_CHANNEL_INFO) {
533816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            program = sLockedChannelProgram;
534816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        } else if (!Program.isValid(program) || TextUtils.isEmpty(program.getTitle())) {
535816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            program = sNoProgram;
536816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        }
5372ea620f3fa5af5bf4ca1a881fd480f0bad34fc1dJaekyun Seok
538816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        if (mLastUpdatedProgram == null
539816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                || !TextUtils.equals(program.getTitle(), mLastUpdatedProgram.getTitle())
540816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                || !TextUtils.equals(program.getEpisodeDisplayTitle(getContext()),
54148dadb49248271b01997862e1335912a4f2e189fYoungsang Cho                mLastUpdatedProgram.getEpisodeDisplayTitle(getContext()))) {
542816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            updateProgramTextView(program);
543816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        }
544816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        updateProgramTimeInfo(program);
545816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
546816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        // When the program is changed, but the previous resize animation has not ended yet,
547816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        // cancel the animation.
548816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        boolean isProgramChanged = !Objects.equals(mLastUpdatedProgram, program);
549816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        if (mResizeAnimator != null && isProgramChanged) {
55048dadb49248271b01997862e1335912a4f2e189fYoungsang Cho            setLastUpdatedProgram(program);
551816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            mProgramInfoUpdatePendingByResizing = true;
552816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            mResizeAnimator.cancel();
553816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        } else if (mResizeAnimator == null) {
554816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            if (mLockType != LOCK_NONE || TextUtils.isEmpty(program.getDescription())) {
555816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                mProgramDescriptionTextView.setVisibility(GONE);
556816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                mProgramDescriptionText = "";
557816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            } else {
558816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                mProgramDescriptionTextView.setVisibility(VISIBLE);
559816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                mProgramDescriptionText = program.getDescription();
560816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            }
561816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            String description = mProgramDescriptionTextView.getText().toString();
562816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            boolean needFadeAnimation = isProgramChanged
563816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                    || !description.equals(mProgramDescriptionText);
564816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            updateBannerHeight(needFadeAnimation);
565816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        } else {
566816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            mProgramInfoUpdatePendingByResizing = true;
5672ea620f3fa5af5bf4ca1a881fd480f0bad34fc1dJaekyun Seok        }
56848dadb49248271b01997862e1335912a4f2e189fYoungsang Cho        setLastUpdatedProgram(program);
56948dadb49248271b01997862e1335912a4f2e189fYoungsang Cho    }
57048dadb49248271b01997862e1335912a4f2e189fYoungsang Cho
57148dadb49248271b01997862e1335912a4f2e189fYoungsang Cho    private void updateProgramInfo(RecordedProgram recordedProgram) {
57248dadb49248271b01997862e1335912a4f2e189fYoungsang Cho        if (mLockType == LOCK_CHANNEL_INFO) {
57348dadb49248271b01997862e1335912a4f2e189fYoungsang Cho            updateProgramInfo(sLockedChannelProgram);
57448dadb49248271b01997862e1335912a4f2e189fYoungsang Cho            return;
57548dadb49248271b01997862e1335912a4f2e189fYoungsang Cho        } else if (recordedProgram == null) {
57648dadb49248271b01997862e1335912a4f2e189fYoungsang Cho            updateProgramInfo(sNoProgram);
57748dadb49248271b01997862e1335912a4f2e189fYoungsang Cho            return;
57848dadb49248271b01997862e1335912a4f2e189fYoungsang Cho        }
57948dadb49248271b01997862e1335912a4f2e189fYoungsang Cho
58048dadb49248271b01997862e1335912a4f2e189fYoungsang Cho        if (mLastUpdatedRecordedProgram == null
58148dadb49248271b01997862e1335912a4f2e189fYoungsang Cho                || !TextUtils.equals(recordedProgram.getTitle(),
58248dadb49248271b01997862e1335912a4f2e189fYoungsang Cho                mLastUpdatedRecordedProgram.getTitle())
58348dadb49248271b01997862e1335912a4f2e189fYoungsang Cho                || !TextUtils.equals(recordedProgram.getEpisodeDisplayTitle(getContext()),
58448dadb49248271b01997862e1335912a4f2e189fYoungsang Cho                mLastUpdatedRecordedProgram.getEpisodeDisplayTitle(getContext()))) {
58548dadb49248271b01997862e1335912a4f2e189fYoungsang Cho            updateProgramTextView(recordedProgram);
58648dadb49248271b01997862e1335912a4f2e189fYoungsang Cho        }
58748dadb49248271b01997862e1335912a4f2e189fYoungsang Cho        updateProgramTimeInfo(recordedProgram);
58848dadb49248271b01997862e1335912a4f2e189fYoungsang Cho
58948dadb49248271b01997862e1335912a4f2e189fYoungsang Cho        // When the program is changed, but the previous resize animation has not ended yet,
59048dadb49248271b01997862e1335912a4f2e189fYoungsang Cho        // cancel the animation.
59148dadb49248271b01997862e1335912a4f2e189fYoungsang Cho        boolean isProgramChanged = !Objects.equals(mLastUpdatedRecordedProgram, recordedProgram);
59248dadb49248271b01997862e1335912a4f2e189fYoungsang Cho        if (mResizeAnimator != null && isProgramChanged) {
59348dadb49248271b01997862e1335912a4f2e189fYoungsang Cho            setLastUpdatedRecordedProgram(recordedProgram);
59448dadb49248271b01997862e1335912a4f2e189fYoungsang Cho            mProgramInfoUpdatePendingByResizing = true;
59548dadb49248271b01997862e1335912a4f2e189fYoungsang Cho            mResizeAnimator.cancel();
59648dadb49248271b01997862e1335912a4f2e189fYoungsang Cho        } else if (mResizeAnimator == null) {
59748dadb49248271b01997862e1335912a4f2e189fYoungsang Cho            if (mLockType != LOCK_NONE
59848dadb49248271b01997862e1335912a4f2e189fYoungsang Cho                    || TextUtils.isEmpty(recordedProgram.getShortDescription())) {
59948dadb49248271b01997862e1335912a4f2e189fYoungsang Cho                mProgramDescriptionTextView.setVisibility(GONE);
60048dadb49248271b01997862e1335912a4f2e189fYoungsang Cho                mProgramDescriptionText = "";
60148dadb49248271b01997862e1335912a4f2e189fYoungsang Cho            } else {
60248dadb49248271b01997862e1335912a4f2e189fYoungsang Cho                mProgramDescriptionTextView.setVisibility(VISIBLE);
60348dadb49248271b01997862e1335912a4f2e189fYoungsang Cho                mProgramDescriptionText = recordedProgram.getShortDescription();
60448dadb49248271b01997862e1335912a4f2e189fYoungsang Cho            }
60548dadb49248271b01997862e1335912a4f2e189fYoungsang Cho            String description = mProgramDescriptionTextView.getText().toString();
60648dadb49248271b01997862e1335912a4f2e189fYoungsang Cho            boolean needFadeAnimation = isProgramChanged
60748dadb49248271b01997862e1335912a4f2e189fYoungsang Cho                    || !description.equals(mProgramDescriptionText);
60848dadb49248271b01997862e1335912a4f2e189fYoungsang Cho            updateBannerHeight(needFadeAnimation);
60948dadb49248271b01997862e1335912a4f2e189fYoungsang Cho        } else {
61048dadb49248271b01997862e1335912a4f2e189fYoungsang Cho            mProgramInfoUpdatePendingByResizing = true;
61148dadb49248271b01997862e1335912a4f2e189fYoungsang Cho        }
61248dadb49248271b01997862e1335912a4f2e189fYoungsang Cho        setLastUpdatedRecordedProgram(recordedProgram);
613816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    }
6142ea620f3fa5af5bf4ca1a881fd480f0bad34fc1dJaekyun Seok
615816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    private void updateProgramTextView(Program program) {
6162ea620f3fa5af5bf4ca1a881fd480f0bad34fc1dJaekyun Seok        if (program == null) {
6172ea620f3fa5af5bf4ca1a881fd480f0bad34fc1dJaekyun Seok            return;
6182ea620f3fa5af5bf4ca1a881fd480f0bad34fc1dJaekyun Seok        }
61948dadb49248271b01997862e1335912a4f2e189fYoungsang Cho        updateProgramTextView(program == sLockedChannelProgram, program.getTitle(),
62048dadb49248271b01997862e1335912a4f2e189fYoungsang Cho                program.getEpisodeTitle(), program.getEpisodeDisplayTitle(getContext()));
62148dadb49248271b01997862e1335912a4f2e189fYoungsang Cho    }
62248dadb49248271b01997862e1335912a4f2e189fYoungsang Cho
62348dadb49248271b01997862e1335912a4f2e189fYoungsang Cho    private void updateProgramTextView(RecordedProgram recordedProgram) {
62448dadb49248271b01997862e1335912a4f2e189fYoungsang Cho        if (recordedProgram == null) {
62548dadb49248271b01997862e1335912a4f2e189fYoungsang Cho            return;
62648dadb49248271b01997862e1335912a4f2e189fYoungsang Cho        }
62748dadb49248271b01997862e1335912a4f2e189fYoungsang Cho        updateProgramTextView(false, recordedProgram.getTitle(), recordedProgram.getEpisodeTitle(),
62848dadb49248271b01997862e1335912a4f2e189fYoungsang Cho                recordedProgram.getEpisodeDisplayTitle(getContext()));
62948dadb49248271b01997862e1335912a4f2e189fYoungsang Cho    }
63007097678613a4ebd094fd8a7ccae5d2aa3fa642aJi-Hwan Lee
63148dadb49248271b01997862e1335912a4f2e189fYoungsang Cho    private void updateProgramTextView(boolean dimText, String title, String episodeTitle,
63248dadb49248271b01997862e1335912a4f2e189fYoungsang Cho            String episodeDisplayTitle) {
633816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        mProgramTextView.setVisibility(View.VISIBLE);
63448dadb49248271b01997862e1335912a4f2e189fYoungsang Cho        if (dimText) {
635816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            mProgramTextView.setTextColor(mChannelBannerDimTextColor);
636816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        } else {
637816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            mProgramTextView.setTextColor(mChannelBannerTextColor);
638816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        }
639816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        updateTextView(mProgramTextView,
640816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                R.dimen.channel_banner_program_large_text_size,
641816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                R.dimen.channel_banner_program_large_margin_top);
64248dadb49248271b01997862e1335912a4f2e189fYoungsang Cho        if (TextUtils.isEmpty(episodeTitle)) {
64348dadb49248271b01997862e1335912a4f2e189fYoungsang Cho            mProgramTextView.setText(title);
644816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        } else {
64548dadb49248271b01997862e1335912a4f2e189fYoungsang Cho            String fullTitle = title + "  " + episodeDisplayTitle;
646816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
647816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            SpannableString text = new SpannableString(fullTitle);
648816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            text.setSpan(new TextAppearanceSpan(getContext(),
649816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                            R.style.text_appearance_channel_banner_episode_title),
65048dadb49248271b01997862e1335912a4f2e189fYoungsang Cho                    fullTitle.length() - episodeDisplayTitle.length(), fullTitle.length(),
651816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                    Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
652816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            mProgramTextView.setText(text);
653816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        }
654816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        int width = mProgramDescriptionTextViewWidth
655816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                - ((mChannelLogoImageView.getVisibility() != View.VISIBLE)
656816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                ? 0 : mChannelLogoImageViewWidth + mChannelLogoImageViewMarginStart);
657816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        ViewGroup.LayoutParams lp = mProgramTextView.getLayoutParams();
658816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        lp.width = width;
659816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        mProgramTextView.setLayoutParams(lp);
660816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        mProgramTextView.measure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
661816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
662816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
663816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        boolean oneline = (mProgramTextView.getLineCount() == 1);
664816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        if (!oneline) {
665816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            updateTextView(
666816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                    mProgramTextView,
667816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                    R.dimen.channel_banner_program_medium_text_size,
668816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                    R.dimen.channel_banner_program_medium_margin_top);
669816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            mProgramTextView.measure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
670816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                    MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
671816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            oneline = (mProgramTextView.getLineCount() == 1);
672816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        }
673816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        updateTopMargin(mAnchorView, oneline
674816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                ? R.dimen.channel_banner_anchor_one_line_y
675816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                : R.dimen.channel_banner_anchor_two_line_y);
676816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    }
677816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
678816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    private void updateProgramTimeInfo(Program program) {
679816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        long startTime = program.getStartTimeUtcMillis();
680816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        long endTime = program.getEndTimeUtcMillis();
681816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        if (mLockType != LOCK_CHANNEL_INFO && startTime > 0 && endTime > startTime) {
682816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            mProgramTimeTextView.setVisibility(View.VISIBLE);
683816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            mRemainingTimeView.setVisibility(View.VISIBLE);
684816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
685816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            mProgramTimeTextView.setText(Utils.getDurationString(
686816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                    getContext(), startTime, endTime, true));
687816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
688816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            long currTime = mMainActivity.getCurrentPlayingPosition();
689816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            if (currTime <= startTime) {
690816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                mRemainingTimeView.setProgress(0);
691816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            } else if (currTime >= endTime) {
692816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                mRemainingTimeView.setProgress(100);
6932ea620f3fa5af5bf4ca1a881fd480f0bad34fc1dJaekyun Seok            } else {
694816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                mRemainingTimeView.setProgress(
695816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                        (int) (100 * (currTime - startTime) / (endTime - startTime)));
6962ea620f3fa5af5bf4ca1a881fd480f0bad34fc1dJaekyun Seok            }
6975dd3c4dda1566c517d50d9534b23cb0f31440a4fJaekyun Seok        } else {
6985dd3c4dda1566c517d50d9534b23cb0f31440a4fJaekyun Seok            mProgramTimeTextView.setVisibility(View.GONE);
6995dd3c4dda1566c517d50d9534b23cb0f31440a4fJaekyun Seok            mRemainingTimeView.setVisibility(View.GONE);
700e51a084c2518f17cee43c86e2f9df907d1f2cafbDongwon Kang        }
701816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    }
7024e5a6a47adb40039a27536236656204f9ad12df3Jaewan Kim
70348dadb49248271b01997862e1335912a4f2e189fYoungsang Cho    private void updateProgramTimeInfo(RecordedProgram recordedProgram) {
70448dadb49248271b01997862e1335912a4f2e189fYoungsang Cho        long durationMs = recordedProgram.getDurationMillis();
70548dadb49248271b01997862e1335912a4f2e189fYoungsang Cho        if (mLockType != LOCK_CHANNEL_INFO && durationMs > 0) {
70648dadb49248271b01997862e1335912a4f2e189fYoungsang Cho            mProgramTimeTextView.setVisibility(View.VISIBLE);
70748dadb49248271b01997862e1335912a4f2e189fYoungsang Cho            mRemainingTimeView.setVisibility(View.VISIBLE);
70848dadb49248271b01997862e1335912a4f2e189fYoungsang Cho
70948dadb49248271b01997862e1335912a4f2e189fYoungsang Cho            mProgramTimeTextView.setText(DateUtils.formatElapsedTime(durationMs / 1000));
71048dadb49248271b01997862e1335912a4f2e189fYoungsang Cho
71148dadb49248271b01997862e1335912a4f2e189fYoungsang Cho            long currTimeMs = mMainActivity.getCurrentPlayingPosition();
71248dadb49248271b01997862e1335912a4f2e189fYoungsang Cho            if (currTimeMs <= 0) {
71348dadb49248271b01997862e1335912a4f2e189fYoungsang Cho                mRemainingTimeView.setProgress(0);
71448dadb49248271b01997862e1335912a4f2e189fYoungsang Cho            } else if (currTimeMs >= durationMs) {
71548dadb49248271b01997862e1335912a4f2e189fYoungsang Cho                mRemainingTimeView.setProgress(100);
71648dadb49248271b01997862e1335912a4f2e189fYoungsang Cho            } else {
71748dadb49248271b01997862e1335912a4f2e189fYoungsang Cho                mRemainingTimeView.setProgress((int) (100 * currTimeMs / durationMs));
71848dadb49248271b01997862e1335912a4f2e189fYoungsang Cho            }
71948dadb49248271b01997862e1335912a4f2e189fYoungsang Cho        } else {
72048dadb49248271b01997862e1335912a4f2e189fYoungsang Cho            mProgramTimeTextView.setVisibility(View.GONE);
72148dadb49248271b01997862e1335912a4f2e189fYoungsang Cho            mRemainingTimeView.setVisibility(View.GONE);
72248dadb49248271b01997862e1335912a4f2e189fYoungsang Cho        }
72348dadb49248271b01997862e1335912a4f2e189fYoungsang Cho    }
72448dadb49248271b01997862e1335912a4f2e189fYoungsang Cho
72548dadb49248271b01997862e1335912a4f2e189fYoungsang Cho    private void setLastUpdatedProgram(Program program) {
72648dadb49248271b01997862e1335912a4f2e189fYoungsang Cho        mLastUpdatedProgram = program;
72748dadb49248271b01997862e1335912a4f2e189fYoungsang Cho        mLastUpdatedRecordedProgram = null;
72848dadb49248271b01997862e1335912a4f2e189fYoungsang Cho    }
72948dadb49248271b01997862e1335912a4f2e189fYoungsang Cho
73048dadb49248271b01997862e1335912a4f2e189fYoungsang Cho    private void setLastUpdatedRecordedProgram(RecordedProgram recordedProgram) {
73148dadb49248271b01997862e1335912a4f2e189fYoungsang Cho        mLastUpdatedProgram = null;
73248dadb49248271b01997862e1335912a4f2e189fYoungsang Cho        mLastUpdatedRecordedProgram = recordedProgram;
73348dadb49248271b01997862e1335912a4f2e189fYoungsang Cho    }
73448dadb49248271b01997862e1335912a4f2e189fYoungsang Cho
735816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    private void updateBannerHeight(boolean needFadeAnimation) {
736816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        Assert.assertNull(mResizeAnimator);
737816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        // Need to measure the layout height with the new description text.
738816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        CharSequence oldDescription = mProgramDescriptionTextView.getText();
739816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        mProgramDescriptionTextView.setText(mProgramDescriptionText);
740816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
741816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        int targetHeight = getMeasuredHeight();
742816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
743816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        if (mCurrentHeight == 0 || !isShown()) {
744816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            // Do not add the resize animation when the banner has not been shown before.
745816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            mCurrentHeight = targetHeight;
746816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            LayoutParams layoutParams = (LayoutParams) getLayoutParams();
747816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            if (targetHeight != layoutParams.height) {
748816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                layoutParams.height = targetHeight;
749816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                setLayoutParams(layoutParams);
750816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            }
751816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        } else if (mCurrentHeight != targetHeight || needFadeAnimation) {
752816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            // Restore description text for fade in/out animation.
753816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            if (needFadeAnimation) {
754816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                mProgramDescriptionTextView.setText(oldDescription);
755816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            }
756816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            mResizeAnimator = createResizeAnimator(targetHeight, needFadeAnimation);
757816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            mResizeAnimator.start();
7582ea620f3fa5af5bf4ca1a881fd480f0bad34fc1dJaekyun Seok        }
7592ea620f3fa5af5bf4ca1a881fd480f0bad34fc1dJaekyun Seok    }
760f533911c31daa05e2ad955434c55b4d412673656Jaekyun Seok
761816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko    private Animator createResizeAnimator(int targetHeight, boolean addFadeAnimation) {
762816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        final ValueAnimator heightAnimator = ValueAnimator.ofInt(mCurrentHeight, targetHeight);
763816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        heightAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
764816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            @Override
765816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            public void onAnimationUpdate(ValueAnimator animation) {
766816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                int value = (Integer) animation.getAnimatedValue();
767816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                LayoutParams layoutParams = (LayoutParams) ChannelBannerView.this.getLayoutParams();
768816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                if (value != layoutParams.height) {
769816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                    layoutParams.height = value;
770816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                    ChannelBannerView.this.setLayoutParams(layoutParams);
771816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                }
772816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko                mCurrentHeight = value;
773816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            }
774816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        });
775816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko
776816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        heightAnimator.setDuration(mResizeAnimDuration);
777816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        heightAnimator.setInterpolator(mResizeInterpolator);
77807097678613a4ebd094fd8a7ccae5d2aa3fa642aJi-Hwan Lee
779816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        if (!addFadeAnimation) {
780816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            heightAnimator.addListener(mResizeAnimatorListener);
781816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko            return heightAnimator;
78207097678613a4ebd094fd8a7ccae5d2aa3fa642aJi-Hwan Lee        }
78384f58a9eacb04bd5951bf33c44ab6c26c01d10f7Ji-Hwan Lee
784816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        AnimatorSet fadeOutAndHeightAnimator = new AnimatorSet();
785816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        fadeOutAndHeightAnimator.playTogether(mProgramDescriptionFadeOutAnimator, heightAnimator);
786816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        AnimatorSet animator = new AnimatorSet();
787816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        animator.playSequentially(fadeOutAndHeightAnimator, mProgramDescriptionFadeInAnimator);
788816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        animator.addListener(mResizeAnimatorListener);
789816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko        return animator;
79007097678613a4ebd094fd8a7ccae5d2aa3fa642aJi-Hwan Lee    }
7912ea620f3fa5af5bf4ca1a881fd480f0bad34fc1dJaekyun Seok}
792